自定义ActionBar 显示规则简析

我们的APP做了做到风格统一和简化代码

通常会统一做一个titleBar

类似这种



这种


总的来说 是这个统一模式


我们可以首先创建一个titleBar 的xml布局,可供我们调试UI
毕竟这个比较于画更简单方便一点

view_action_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="@dimen/space_45">

    <TextView
        android:id="@+id/left_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"/>

    <ImageView
        android:id="@+id/left_image"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:layout_centerVertical="true"
        android:padding="10dp"
        android:scaleType="fitStart"
        android:src="@drawable/icon_arrow_left_green"/>


    <TextView
        android:id="@+id/title_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:ellipsize="end"
        android:maxEms="8"
        android:singleLine="true"
        android:text="主页"
        android:textColor="@color/black"
        android:textSize="@dimen/text_size_17"/>

    <ImageView
        android:id="@+id/title_image"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:layout_centerVertical="true"
        android:padding="15dp"
        android:scaleType="fitStart"/>

    <RelativeLayout
        android:id="@+id/right_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true">

        <TextView
            android:id="@+id/right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="导航"
            android:textColor="@color/green01"
            android:textSize="@dimen/text_size_16"/>

        <ImageView
            android:id="@+id/right_image"
            android:layout_width="42dp"
            android:layout_height="42dp"
            android:padding="10dp"
            android:scaleType="fitEnd"/>
    </RelativeLayout>

    <TextView
        android:id="@+id/subtitle_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="@dimen/space_px_20"
        android:text="副标题"
        android:layout_toLeftOf="@id/right_container"
        android:textColor="@color/green01"
        android:textSize="@dimen/text_size_16"/>

    <View
        android:id="@+id/bottom_line"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_alignParentBottom="true"
        android:background="@color/gray_line"/>
</RelativeLayout>

下面开始准备自定义的属性了 attrs 下
<declare-styleable name="MyActionBar">
        <attr name="title_text" format="string" />
        <attr name="subtitle_text" format="string" />
        <attr name="title_text_size" format="dimension" />
        <attr name="title_text_color" format="color" />
        <attr name="title_image" format="reference" />
        <attr name="title_image_width" format="dimension" />
        <attr name="title_image_height" format="dimension" />
        <attr name="right_text" format="string" />
        <attr name="right_text_size" format="dimension" />
        <attr name="right_text_color" format="color" />
        <attr name="right_image" format="reference" />
        <attr name="right_image_width" format="dimension" />
        <attr name="right_image_height" format="dimension" />
        <attr name="left_text" format="string" />
        <attr name="left_text_size" format="dimension" />
        <attr name="left_text_color" format="color" />
        <attr name="left_image" format="reference" />
        <attr name="left_image_width" format="dimension" />
        <attr name="left_image_height" format="dimension" />
        <attr name="line_visible" format="boolean" />
        <attr name="child_visible">
            <flag name="LT" value="0x01" />
            <flag name="LI" value="0x02" />
            <flag name="TT" value="0x04" />
            <flag name="TI" value="0x08" />
            <flag name="RT" value="0x10" />
            <flag name="RI" value="0x20" />
            <flag name="ST" value="0x40" />
            <flag name="NULL" value="0x00" />
        </attr>
    </declare-styleable>
当然重点就是child_visible 这个枚举属性的定义了


这里给出我们自定义的控件
MyActionBar.class
public class MyActionBar extends RelativeLayout implements View.OnClickListener {
    private static final int LEFT_TEXT_VISIBLE = 0x01;
    private static final int LEFT_IMAGE_VISIBLE = 0x02;
    private static final int TITLE_TEXT_VISIBLE = 0x04;
    private static final int TITLE_IMAGE_VISIBLE = 0x08;
    private static final int RIGHT_TEXT_VISIBLE = 0x10;
    private static final int RIGHT_IMAGE_VISIBLE = 0x20;
    private static final int SUBTITLE_TEXT_VISIBLE = 0x40;
    private TextView mLeftTextView;
    private ImageView mLeftImageView;
    private TextView mTitleTextView;
    private TextView mSbutitleTextView;
    private ImageView mTitleImageView;
    private TextView mRightTextView;
    private ImageView mRightImageView;
    private View mBottomLine;

    private Drawable background = null;
    private int mChildVisible = 0x06;
    private String mTitleText;
    private String mSubTitleText;
    private int mTitleTextSize = -1;
    private int mTitleTextColor = -1;
    private int mTitleImage;
    private int mTitleImageWidth;
    private int mTitleImageHeight;

    private String mLeftText;
    private int mLeftTextSize;
    private int mLeftTextColor;
    private Drawable mLeftDrawable;
    private int mLeftDrawableWidth;
    private int mLeftDrawableHeight;

    private boolean isLineVisible = true;
    private String mRightText;
    private int mRightTextSize;
    private ColorStateList mRightTextColor;
    private Drawable mRightDrawable;
    private int mRightDrawableWidth;
    private int mDRightrawableHeight;
    private OnActionBarClickListener listener;

    public MyActionBar(Context context) {
        super(context);
        initActionBarView();
    }

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

    public MyActionBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (getBackground() == null) {
            setBackgroundColor(getResources().getColor(R.color.gray_title));
        }
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyActionBar, defStyle, 0);
        for (int i = 0; i < typedArray.getIndexCount(); i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.MyActionBar_child_visible:
                    mChildVisible = typedArray.getInt(attr, mChildVisible);
                    break;
                case R.styleable.MyActionBar_title_text:
                    mTitleText = typedArray.getString(attr);
                    break;
                case R.styleable.MyActionBar_subtitle_text:
                    mSubTitleText = typedArray.getString(attr);
                    break;
                case R.styleable.MyActionBar_title_text_size:
                    mTitleTextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.MyActionBar_title_text_color:
                    mTitleTextColor = typedArray.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.MyActionBar_title_image:
                    break;
                case R.styleable.MyActionBar_title_image_width:
                    break;
                case R.styleable.MyActionBar_title_image_height:
                    break;
                case R.styleable.MyActionBar_left_text:
                    break;
                case R.styleable.MyActionBar_left_text_size:
                    break;
                case R.styleable.MyActionBar_left_text_color:
                    break;
                case R.styleable.MyActionBar_left_image:
                    mLeftDrawable = typedArray.getDrawable(attr);
                    break;
                case R.styleable.MyActionBar_left_image_width:
                    break;
                case R.styleable.MyActionBar_left_image_height:
                    break;
                case R.styleable.MyActionBar_right_text:
                    mRightText = typedArray.getString(attr);
                    break;
                case R.styleable.MyActionBar_right_text_size:
                    break;
                case R.styleable.MyActionBar_right_text_color:
                    mRightTextColor = typedArray.getColorStateList(attr);
                    break;
                case R.styleable.MyActionBar_right_image:
                    mRightDrawable = typedArray.getDrawable(attr);
                    break;
                case R.styleable.MyActionBar_right_image_width:
                    break;
                case R.styleable.MyActionBar_right_image_height:
                    break;
                case R.styleable.MyActionBar_line_visible:
                    isLineVisible = typedArray.getBoolean(attr, true);
                    break;
            }
        }
        typedArray.recycle();
        initActionBarView();
        initActionBarData();
        initActionBarVisible();
    }


    private void initActionBarView() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setPadding(getPaddingLeft(), getPaddingTop() + DensityUtils.getStatusBarHeight(getContext()),
                    getPaddingRight(), getPaddingBottom());
        }
        View view = View.inflate(getContext(), R.layout.view_action_bar, null);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, DensityUtils.dip2px(getContext(), 45));
        view.setLayoutParams(layoutParams);
        mLeftTextView = (TextView) view.findViewById(R.id.left_text);
        mLeftTextView.setOnClickListener(this);
        mLeftImageView = (ImageView) view.findViewById(R.id.left_image);
        mLeftImageView.setOnClickListener(this);
        mTitleTextView = (TextView) view.findViewById(R.id.title_text);
        mTitleTextView.setOnClickListener(this);
        mTitleImageView = (ImageView) view.findViewById(R.id.title_image);
        mTitleImageView.setOnClickListener(this);
        mSbutitleTextView = (TextView) view.findViewById(R.id.subtitle_text);
        mSbutitleTextView.setOnClickListener(this);
        mRightTextView = (TextView) view.findViewById(R.id.right_text);
        mRightTextView.setOnClickListener(this);
        mRightImageView = (ImageView) view.findViewById(R.id.right_image);
        mRightImageView.setOnClickListener(this);
        mBottomLine = view.findViewById(R.id.bottom_line);
        addView(view);
    }

    private void initActionBarData() {
        if (!TextUtils.isEmpty(mTitleText)) {
            mTitleTextView.setText(mTitleText);
        }
        if (!TextUtils.isEmpty(mSubTitleText)) {
            mSbutitleTextView.setText(mSubTitleText);
        }
        if (mTitleTextSize != -1) {
            mTitleTextView.setTextSize(DensityUtils.sp2px(getContext(), mTitleTextSize));
        }
        if (mTitleTextColor != -1) {
            mTitleTextView.setTextColor(mTitleTextColor);
        }

        if (mLeftDrawable != null) {
            mLeftImageView.setImageDrawable(mLeftDrawable);
        }

        if (!TextUtils.isEmpty(mRightText)) {
            mRightTextView.setText(mRightText);
        }

        if (mRightDrawable != null) {
            mRightImageView.setImageDrawable(mRightDrawable);
        }

        mRightTextView.setTextColor(mRightTextColor != null ? mRightTextColor : ColorStateList.valueOf(0xFF32A238));
    }

    private void initActionBarVisible() {
        if ((LEFT_TEXT_VISIBLE & mChildVisible) == 0) {
            mLeftTextView.setVisibility(View.GONE);
        } else {
            mLeftTextView.setVisibility(View.VISIBLE);
        }
        if ((LEFT_IMAGE_VISIBLE & mChildVisible) == 0) {
            mLeftImageView.setVisibility(View.GONE);
        } else {
            mLeftImageView.setVisibility(View.VISIBLE);
        }
        if ((TITLE_TEXT_VISIBLE & mChildVisible) == 0) {
            mTitleTextView.setVisibility(View.GONE);
        } else {
            mTitleTextView.setVisibility(View.VISIBLE);
        }
        if ((TITLE_IMAGE_VISIBLE & mChildVisible) == 0) {
            mTitleImageView.setVisibility(View.GONE);
        } else {
            mTitleImageView.setVisibility(View.VISIBLE);
        }
        if ((RIGHT_TEXT_VISIBLE & mChildVisible) == 0) {
            mRightTextView.setVisibility(View.GONE);
        } else {
            mRightTextView.setVisibility(View.VISIBLE);
        }
        if ((RIGHT_IMAGE_VISIBLE & mChildVisible) == 0) {
            mRightImageView.setVisibility(View.GONE);
        } else {
            mRightImageView.setVisibility(View.VISIBLE);
        }
        if ((SUBTITLE_TEXT_VISIBLE & mChildVisible) == 0) {
            mSbutitleTextView.setVisibility(View.GONE);
        } else {
            mSbutitleTextView.setVisibility(View.VISIBLE);
        }
        if (isLineVisible) {
            mBottomLine.setVisibility(View.VISIBLE);
        } else {
            mBottomLine.setVisibility(View.GONE);
        }
    }

    @Override
    public void onClick(View v) {
        if (listener == null) {
            return;
        }
        switch (v.getId()) {
            case R.id.left_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_LEFT_TEXT);
                break;
            case R.id.left_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_LEFT_IMAGE);
                break;
            case R.id.title_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_TITLE_TEXT);
                break;
            case R.id.title_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_TITLE_IMAGE);
                break;
            case R.id.right_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_RIGHT_TEXT);
                break;
            case R.id.right_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_RIGHT_IMAGE);
                break;
            case R.id.subtitle_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_SUBTITLE_TEXT);
                break;
        }
    }


    public void setTitleText(String text) {
        mTitleTextView.setText(text);
    }

    public TextView getRightTextView() {
        return mRightTextView;
    }

    public void setRightText(String text) {
        mRightTextView.setText(text);
    }

    public void setRightTextColor(int color) {
        mRightTextView.setTextColor(color);
    }

    public void setRightVisibility(int visibility) {
        mRightTextView.setVisibility(visibility);
    }

    public void setRightTextClickable(boolean clickable) {
        mRightTextView.setClickable(clickable);
    }

    public interface OnActionBarClickListener {
        int POS_LEFT_TEXT = 0;
        int POS_LEFT_IMAGE = 1;
        int POS_TITLE_TEXT = 2;
        int POS_TITLE_IMAGE = 3;
        int POS_RIGHT_TEXT = 4;
        int POS_RIGHT_IMAGE = 5;
        int POS_SUBTITLE_TEXT = 6;

        void onActionBarClick(View view, int postion);
    }

    public void setOnActionBarClickListener(OnActionBarClickListener listener) {
        this.listener = listener;
    }
}

下面具体解释下
1.首先我们在2个参数的构造方法中初始化我们子控件的显示属性


2. 在 initActionBarView()方法中建立各个子控件的引用
3. 在 initActionBarData()方法中的到子控件显示值
4. 在 initActionBarVisible()方法中的初始化子控件的显示问题。

下面重点来了,我贴一下控件的使用,在仔细讲解
 <com.ruiyi.view.ui.MyActionBar
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:child_visible="LI|TT|RI"
        app:right_image="@drawable/icon_help_info"
        app:title_text="@string/apply_card_car_step3_title" />

我们对属性child_visible 指定为 LI | TT | RI 采取的是 | 运算
我简单解释一下或运算
   参加运算的两个对象,按二进制位进行“或”运算。
   运算规则:0|0=0;   0|1=1;   1|0=1;    1|1=1;
   即 :参加运算的两个对象只要有一个为1,其值为1。
   例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111   因此,3|5的值得7。

这里我们的定义为
 LI = 0x02 = 0000 0010
 TT = 0x04  0000 0100
 RI = 0x20  0001 0100
LI|TT|RI = 0001 0110 = Ox21
在自定义控件中得到的mChildVisivible = 0x21

在判断显示的时候,我们采取的是& 运算
我简单解释一下与运算
运算规则:0&0=0;   0&1=0;    1&0=0;     1&1=1;
即:两位同时为“1”,结果才为“1”,否则为0
例如:3&5  即 0000 0011 & 0000 0101 = 0000 0001   因此,3&5的值得1。

我们的判断规则是
 if ((LEFT_TEXT_VISIBLE & mChildVisible) == 0) {
            mLeftTextView.setVisibility(View.GONE);
        } else {
            mLeftTextView.setVisibility(View.VISIBLE);
        }
        if ((LEFT_IMAGE_VISIBLE & mChildVisible) == 0) {
            mLeftImageView.setVisibility(View.GONE);
        } else {
            mLeftImageView.setVisibility(View.VISIBLE);
        }
        if ((TITLE_TEXT_VISIBLE & mChildVisible) == 0) {
            mTitleTextView.setVisibility(View.GONE);
        } else {
            mTitleTextView.setVisibility(View.VISIBLE);
        }

当运算结果为0 ,子控件隐藏,反之就显示

这里我简单验证下

left text : 0000 0001 & 0001 0110 = 0000 0000 = 0 不显示
left image : 0000 0010 & 0001 0110 = 0000 0010 = 2 显示
title text : 0000 0100 & 0001 0110 = 0000 0100 = 8 显示
title image: 0000 1000 & 0001 0110 = 0000 0000 = 0 不显示

这就是显示规则的原理了。

最后 我们可以将各个子控件的点击事件抽离处理,运用回调处理
我们创建一个接口,包括View 和标记
  public interface OnActionBarClickListener {
        int POS_LEFT_TEXT = 0;
        int POS_LEFT_IMAGE = 1;
        int POS_TITLE_TEXT = 2;
        int POS_TITLE_IMAGE = 3;
        int POS_RIGHT_TEXT = 4;
        int POS_RIGHT_IMAGE = 5;
        int POS_SUBTITLE_TEXT = 6;

        void onActionBarClick(View view, int postion);
    }
拿到listener
  public void setOnActionBarClickListener(OnActionBarClickListener listener) {
        this.listener = listener;
    }
给每个子控件设置点击事件,统一处理
     mLeftTextView.setOnClickListener(this);
        mLeftImageView = (ImageView) view.findViewById(R.id.left_image);
        mLeftImageView.setOnClickListener(this);
        mTitleTextView = (TextView) view.findViewById(R.id.title_text);
        mTitleTextView.setOnClickListener(this);
        mTitleImageView = (ImageView) view.findViewById(R.id.title_image);
        mTitleImageView.setOnClickListener(this);
        mSbutitleTextView = (TextView) view.findViewById(R.id.subtitle_text);
        mSbutitleTextView.setOnClickListener(this);
        mRightTextView = (TextView) view.findViewById(R.id.right_text);
        mRightTextView.setOnClickListener(this);
        mRightImageView = (ImageView) view.findViewById(R.id.right_image);
        mRightImageView.setOnClickListener(this);

统一处理回传
@Override
    public void onClick(View v) {
        if (listener == null) {
            return;
        }
        switch (v.getId()) {
            case R.id.left_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_LEFT_TEXT);
                break;
            case R.id.left_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_LEFT_IMAGE);
                break;
            case R.id.title_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_TITLE_TEXT);
                break;
            case R.id.title_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_TITLE_IMAGE);
                break;
            case R.id.right_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_RIGHT_TEXT);
                break;
            case R.id.right_image:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_RIGHT_IMAGE);
                break;
            case R.id.subtitle_text:
                listener.onActionBarClick(v, OnActionBarClickListener.POS_SUBTITLE_TEXT);
                break;
        }
    }
在收到事件,我们自己处理
  @Override
    public void onActionBarClick(View v, int postion) {
        super.onActionBarClick(v, postion);
        if (postion == POS_RIGHT_TEXT) {
          。。。。
        }
    }

嗯,就这样!






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值