自定义ActionBar 显示规则简析
来源:互联网 发布:js原型对象 编辑:程序博客网 时间:2024/06/05 16:38
我们的APP做了做到风格统一和简化代码
这种
总的来说 是这个统一模式
我们可以首先创建一个titleBar 的xml布局,可供我们调试UI
毕竟这个比较于画更简单方便一点
view_action_bar.xml
下面开始准备自定义的属性了 attrs 下
这里给出我们自定义的控件
MyActionBar.class
下面具体解释下
1.首先我们在2个参数的构造方法中初始化我们子控件的显示属性
2. 在 initActionBarView()方法中建立各个子控件的引用
3. 在 initActionBarData()方法中的到子控件显示值
4. 在 initActionBarVisible()方法中的初始化子控件的显示问题。
下面重点来了,我贴一下控件的使用,在仔细讲解
我们对属性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。
我们的判断规则是
当运算结果为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 和标记
统一处理回传
嗯,就这样!
通常会统一做一个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) { 。。。。 } }
嗯,就这样!
0 0
- 自定义ActionBar 显示规则简析
- Actionbar 自定义多个TextView滚动显示
- ActionBar自定义操作栏、无法显示
- android 自定义actionbar+字符串滚动显示
- 自定义 ActionBar
- 自定义actionBar
- 自定义actionbar
- 自定义actionbar
- 自定义Actionbar
- 自定义ActionBar
- 自定义ActionBar
- 自定义ActionBar
- 自定义Actionbar
- 自定义actionbar
- ActionBar自定义
- 自定义ActionBar
- 自定义ActionBar
- ActionBar自定义
- 生成PKI公私密钥对及数字证书
- 微信,QQ这类IM app怎么做——谈谈Websocket
- Java中的异常,异常处理和设计
- Windows学习总结(3)——成为电脑高手必备的cmd命令大全
- java入门教程-7.10Java线程死锁
- 自定义ActionBar 显示规则简析
- centos6.5和centos7如何搭建php环境
- C盘的 bat批处理代码
- try&catch
- 真相:九成人认为想加薪还得靠跳槽
- 一起学Netty(十六)之 ChannelOption的TCP_NODELAY属性设置
- 深入了解iostream
- Spring hello world实例
- gcc 使用方法