Android 通用标题栏组合控件

由于项目中经常用到此种组合控件,就封装了下,具体效果看下图,老司机可以绕道哈!

《Android 通用标题栏组合控件》

Image.png

一、主要功能
  • 支持左右图标动态设置
  • 支持左右、中间文字动态修改
  • 支持字体大小、颜色修改
  • 支持左右图标,左中右文字隐藏显示
  • 支持左右图标和文案的点击监听
二、基本使用方式

   

三、基本属性介绍

属性名属性说明属性值
titleBarBackground标题栏背景色color,reference,默认为white
leftImage左边图片reference
leftImageVisiable左边图片是否可见boolean,默认为true,显示控件
leftText左边文案string,reference
leftTextVisibale左边文案是否可见boolean,默认为true,显示控件
leftTextFontSize左边文案字体大小dimension,reference,默认为16sp
leftTextColor左边文案字体颜色color,reference
midText中间文案string,reference
midTextVisiable中间文案是否可见boolean,默认为true,显示控件
midTextFontSize中间文案字体大小dimension,reference,默认为18sp
midTextFontColor中间文案字体颜色color,reference
rightText右边文案color,reference
rightTextVisible右边文案是否可见boolean,默认为true,显示控件
rightTextFontSize右边文案字体大小dimension,reference,默认为16sp
rightTextColor右边文案字体颜色color,reference
rightImage右边图片reference
rightImageVisible右边图片是否可见boolean,默认为true,显示控件

四、组合控件类

package com.example.android.customvView;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.android.R;

/**
 * Created by WangLu on 2016/12/6.
 * E-mail:wang_lu90125@163.com
 */

public class CustomNavigatorBar extends RelativeLayout implements View.OnClickListener {

    private ImageView leftImage;
    private TextView leftText;
    private TextView midText;
    private ImageView rightImage;
    private TextView rightText;
    private OnCustomClickListener customClickListener ;

    public CustomNavigatorBar(Context context) {
        this(context,null);
    }

    public CustomNavigatorBar(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CustomNavigatorBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        iniView(context);
        /**
         * 两种初始化的不同,请看下面注释讲解
         */
        initOneType(context, attrs);//第一种初始化
//        initTwoType(context, attrs);//第二种初始化
    }

    private void iniView(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.custom_title_bar, this, true);
        leftImage = (ImageView) view.findViewById(R.id.left_image);
        leftText = (TextView) view.findViewById(R.id.left_text);
        midText = (TextView) view.findViewById(R.id.mid_text);
        rightText = (TextView) view.findViewById(R.id.right_text);
        rightImage = (ImageView) view.findViewById(R.id.right_image);

    }

    /**
     * 有兴趣的请参考鸿洋大神的自定义讲解
     *
     * 初始化属性值:这种写法,不管你在布局中有没有使用该属性,都会执行getXXX方法赋值
     *假设一个场景:
     *    private int attr_mode = 1;//默认为1
     *   //然后你在写getXXX方法的时候,是这么写的:
     *   attr_mode = array.getInt(i, 0);
     *
     *   可能你的自定义属性有个默认的值,然后你在写赋值的时候,一看是整形,就默默的第二个参数就给了个0,
     *   然而用户根本没有在布局文件里面设置这个属性,你却在运行时将其变为了0(而不是默认值),而第二种就不存在这个问题。
     *   当然这个场景可以由规范的书写代码的方式来避免,(把默认值提取出来,都设置对就好了)。
     *
     * 场景二:
     *
     *   其实还有个场景,假设你是继承自某个View,父类的View已经对该成员变量进行赋值了,然后你这边需要根据用户的设置情况,
     *   去更新这个值,第一种写法,如果用户根本没有设置,你可能就将父类的赋值给覆盖了。
     *
     * @param context
     * @param attrs
     */
    private void initTwoType(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNavigatorBar);
        if (null != typedArray) {
            Drawable leftDrawable = typedArray.getDrawable(R.styleable.CustomNavigatorBar_leftImage);
            leftImage.setImageDrawable(leftDrawable);

            boolean leftImageVisible = typedArray.getBoolean(R.styleable.CustomNavigatorBar_leftImageVisiable, false);
            if (leftImageVisible) {
                leftImage.setVisibility(View.VISIBLE);
            } else {
                leftImage.setVisibility(View.GONE);
            }

            typedArray.recycle();
        }
    }

    /**注:如果switch报错,请改为if-else
     * 初始化属性值:这种写法,只有在布局中设置了该属性值后,才会调用getXXX()方法赋值
     * @param context
     * @param attrs
     */
    private void initOneType(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNavigatorBar);
        int totalAttributes = typedArray.getIndexCount();
        for (int i = 0 ; i
   

五、attrs.xml


   

    
     
      
       
        
         
          
           
            
             
              
               
                
                 
                  
                   
                    
                     
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
     
   

六、组合控件布局(custom_title_bar.xml)

  为什么使用merge,因为组合控件已经extends RelativeLayout,如果根布局还是用viewGroup的话,会使布局重复嵌套,影响View的绘制性能;

   

    
     
      
       
        
         
          
         
        
        
      
     
    
   

七、具体使用

CustomNavigatorBar customNavigatorBar = (CustomNavigatorBar) findViewById(R.id.customView);
        /**
         * 第一种监听的具体实现
         */
        customNavigatorBar.setLeftImageOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,"left",Toast.LENGTH_SHORT).show();
            }
        });

        /**
         * 第二种监听的具体实现
         */
        customNavigatorBar.addViewClickListener(new CustomNavigatorBar.OnCustomClickListener() {
            @Override
            public void onClickListener(View rootView) {
                switch (rootView.getId()) {
                    case R.id.right_image:
                        Toast.makeText(MainActivity.this,"right_image is clicked",Toast.LENGTH_SHORT).show();
                        break ;
                    case R.id.left_image:
                        Toast.makeText(MainActivity.this,"left_image is clicked",Toast.LENGTH_SHORT).show();
                        break ;
                }
            }
        });

八、github仓库

如有什么问题,敬请提出,十分感谢!希望越来越好,谢谢!

如果喜欢,还请点击start,喜欢支持一下了,谢谢O(∩_∩)O~。

    原文作者:Android
    原文地址: https://juejin.im/entry/5847c1d8128fe10057978b4e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞