我们的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) {
。。。。
}
}
嗯,就这样!