Android通用標題欄組合控件
由于項目中經常用到此種組合控件,就封裝了下,具體效果看下圖,老司機可以繞道哈!
Image.png
一、主要功能
- 支持左右圖標動態設置
- 支持左右、中間文字動態修改
- 支持字體大小、顏色修改
- 支持左右圖標,左中右文字隱藏顯示
- 支持左右圖標和文案的點擊監聽
二、基本使用方式
<com.example.android.customvView.CustomNavigatorBar
android:id="@+id/customView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:leftImage="@drawable/leftarrow"
app:rightImage="@drawable/rightarrow"
app:leftImageVisiable="true"
app:rightImageVisible="true"
app:leftText="左邊"
app:rightText="右邊"
app:midText="標題"
app:midTextFontColor="#ffffff"
app:leftTextColor="#ffffff"
app:rightTextColor="@color/colorAccent"
app:titleBarBackground="@color/colorPrimary"
app:midTextFontSize="18px"
app:leftTextVisibale="true"
app:rightTextVisible="true"
app:leftTextFontSize="16px"
app:rightTextFontSize="16px"
/>
三、基本屬性介紹
屬性名 | 屬性說明 | 屬性值 |
---|---|---|
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<totalAttributes ;i++) {
int index = typedArray.getIndex(i);
switch (index) {
case R.styleable.CustomNavigatorBar_leftImage:
leftImage.setImageDrawable(typedArray.getDrawable(index));
break ;
case R.styleable.CustomNavigatorBar_leftImageVisiable:
getVisible(typedArray,leftImage,index);
break ;
case R.styleable.CustomNavigatorBar_leftText:
leftText.setText(typedArray.getString(index));
break ;
case R.styleable.CustomNavigatorBar_leftTextFontSize:
leftText.setTextSize(typedArray.getDimensionPixelSize(index, (int) sp2px(context,16)));
break ;
case R.styleable.CustomNavigatorBar_leftTextColor:
leftText.setTextColor(typedArray.getColor(index, Color.WHITE));
break ;
case R.styleable.CustomNavigatorBar_leftTextVisibale:
getVisible(typedArray,leftText,index);
break ;
case R.styleable.CustomNavigatorBar_midText:
midText.setText(typedArray.getString(index));
break ;
case R.styleable.CustomNavigatorBar_midTextVisiable:
getVisible(typedArray,midText,index);
break ;
case R.styleable.CustomNavigatorBar_midTextFontSize:
midText.setTextSize(typedArray.getDimensionPixelSize(index,(int) sp2px(context,18)));
break ;
case R.styleable.CustomNavigatorBar_midTextFontColor:
midText.setTextColor(typedArray.getColor(index,Color.WHITE));
case R.styleable.CustomNavigatorBar_rightImage:
rightImage.setImageDrawable(typedArray.getDrawable(index));
break ;
case R.styleable.CustomNavigatorBar_rightImageVisible:
getVisible(typedArray,rightImage,index);
break ;
case R.styleable.CustomNavigatorBar_rightText:
rightText.setText(typedArray.getString(index));
break ;
case R.styleable.CustomNavigatorBar_rightTextFontSize:
rightText.setTextSize(typedArray.getDimensionPixelSize(index,(int) sp2px(context,16)));
break ;
case R.styleable.CustomNavigatorBar_rightTextColor:
rightText.setTextColor(typedArray.getColor(index, Color.WHITE));
break ;
case R.styleable.CustomNavigatorBar_rightTextVisible:
getVisible(typedArray,rightText,index);
break ;
case R.styleable.CustomNavigatorBar_titleBarBackground:
int titleBarBackgroundColor = typedArray.getColor(index, Color.GREEN);
setBackgroundColor(titleBarBackgroundColor);
break ;
}
}
typedArray.recycle();
}
/**
* 用來隱藏顯示View,只有gone 和 visible兩種情況,因為inVisible感到在這里用不到,就沒有封裝
* @param typedArray
* @param view
* @param index
*/
private void getVisible(TypedArray typedArray ,View view,int index) {
boolean visible = typedArray.getBoolean(index, false);
if (visible) {
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
}
private void setVisible(View view ,boolean visible) {
if (visible) {
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
}
/**
* 兩種監聽只能使用其中一種,不能同時使用
*
* ----------------------------第一種點擊監聽開始處----------------------------------------
* @param clickListener
*/
public void setLeftImageOnClickListener(View.OnClickListener clickListener) {
if (null != clickListener) {
leftImage.setOnClickListener(clickListener);
}
}
public void setLeftTextOnClickListener(View.OnClickListener clickListener) {
if (null != clickListener) {
leftText.setOnClickListener(clickListener);
}
}
public void setRightImageOnClickListener(View.OnClickListener clickListener) {
if (null != clickListener) {
rightImage.setOnClickListener(clickListener);
}
}
public void setRightTextOnClickListener(View.OnClickListener clickListener) {
if (null != clickListener) {
rightText.setOnClickListener(clickListener);
}
}
/**
* ----------------------------第二種點擊監聽開始處----------------------------------------
* @return
*/
public void addViewClickListener(OnCustomClickListener listener) {
leftText.setOnClickListener(this);
leftImage.setOnClickListener(this);
rightImage.setOnClickListener(this);
rightText.setOnClickListener(this);
this.customClickListener = listener ;
}
public interface OnCustomClickListener{
void onClickListener(View rootView);
}
@Override
public void onClick(View view) {
customClickListener.onClickListener(view);
}
/**
* ----------------------------第二種點擊監聽結束處----------------------------------------
* @return
*/
public ImageView getLeftImageView(){
return leftImage;
}
public ImageView getRightImage(){
return rightImage;
}
public TextView getLeftText(){
return leftText;
}
public TextView getRightText(){
return rightText;
}
public TextView getMidText(){
return midText;
}
/**
* 設置textView的標題內容
* @param textDescribe
*/
public void setLeftText(String textDescribe) {
if (null != textDescribe) {
leftText.setText(textDescribe);
}
}
public void setMidText(String textDescribe) {
if (null != textDescribe) {
midText.setText(textDescribe);
}
}
public void setRightText(String textDescribe) {
if (null != textDescribe) {
rightText.setText(textDescribe);
}
}
/**
* 設置textView的字體顏色
* @param textColor
*/
public void setLeftTextColor(int textColor) {
leftText.setTextColor(textColor);
}
public void setMidTextColor(int textColor) {
midText.setText(textColor);
}
public void setRightTextColor(int textColor) {
rightText.setText(textColor);
}
/**
* 設置title欄背景色
* @param color
*/
public void setTitleBarBackground(int color) {
setBackgroundColor(color);
}
/**
* 左右控件的隱藏顯示
* @param visible
*/
public void setLeftImageVisible(boolean visible) {
setVisible(leftImage, visible);
}
public void setLeftTextVisible(boolean visible) {
setVisible(leftText, visible);
}
public void setRifhtImageVisible(boolean visible) {
setVisible(rightImage, visible);
}
public void setRightTextVisible(boolean visible) {
setVisible(rightText, visible);
}
private float sp2px(Context context, float defaultVal) {
float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, defaultVal, context.getResources().getDisplayMetrics());
return applyDimension ;
}
private float dp2px(Context context, float defaultVal) {
float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, defaultVal, context.getResources().getDisplayMetrics());
return applyDimension ;
}
private float dp2px(Context context, int defultVal) {
float scale = context.getResources().getDisplayMetrics().density;
return (float) (defultVal*scale + 0.5);
}
}
五、attrs.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name = "CustomNavigatorBar">
<attr name="titleBarBackground" format="reference|color" />
<attr name="leftImage" format="reference" />
<attr name="leftImageVisiable" format="boolean" />
<attr name="leftText" format="string|reference" />
<attr name="leftTextVisibale" format="boolean" />
<attr name="leftTextFontSize" format="dimension|reference" />
<attr name="leftTextColor" format="color|reference" />
<attr name="midText" format="string|reference" />
<attr name="midTextVisiable" format="boolean" />
<attr name="midTextFontSize" format="dimension|reference" />
<attr name="midTextFontColor" format="color|reference" />
<attr name="rightText" format="string|reference" />
<attr name="rightTextVisible" format="boolean" />
<attr name="rightTextFontSize" format="dimension|reference" />
<attr name="rightTextColor" format="color|reference" />
<attr name="rightImage" format="reference" />
<attr name="rightImageVisible" format="boolean" />
</declare-styleable>
</resources>
六、組合控件布局(custom_title_bar.xml)
為什么使用merge,因為組合控件已經extends RelativeLayout,如果根布局還是用viewGroup的話,會使布局重復嵌套,影響View的繪制性能;
<?xml version = "1.0" encoding = "utf-8" ?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/left_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:minHeight="20dp"
android:minWidth="20dp"
android:layout_marginLeft="10dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/left_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@+id/left_image"
android:gravity="center"
android:minHeight="45dp"
android:text="left" />
<TextView
android:id="@+id/mid_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minHeight="45dp"
android:text="mid"
android:textSize="17sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minHeight="45dp"
android:orientation="horizontal">
<TextView
android:id="@+id/right_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_toLeftOf="@+id/right_image"
android:gravity="center"
android:minHeight="45dp"
android:text="right" />
<ImageView
android:id="@+id/right_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:minHeight="20dp"
android:minWidth="20dp"
android:src="@drawable/ic_launcher" />
</LinearLayout>
</merge>
七、具體使用
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 ;
}
}
});
來自:http://www.jianshu.com/p/b693d5ca29fd
本文由用戶 anzhuo 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!