android組合控件Titlebar的定制
來自: http://blog.csdn.net/ydxlt/article/details/50805822
前言:我相信”天生我才必有用”這句話,每個人都有他的作用,也許他的作用相對其他人來不是很明顯,也許他的作用也就是取悅別人,但是請不要忘記,可以通過不斷努力來發揮自己的作用,使自己的價值得到提升。
在平時的android開發中你是否遇到一個問題,那就是每次都要自己寫一個布局,或者是引入一個布局但每次都要為了給布局中的控件初始化。對于這個問題,谷歌官方推出了ActionBar,以及隨后的取代ActionBar的ToolBar來使我們的開發更加簡單,如:使用ToolBar+DrawLayout就非常容易實現推酷app的那種菜單效果。這樣的一個控件的出現極大地減少了程序員的負擔,使得android開發越來越簡單,相信以后將會有更多類似的好的控件的出現來簡化我們app的開發,呵呵,滿期待的~。
這篇文章將介紹一個自己組合的控件Titlebar來簡化我們的開發,這個組合控件的實現是個體力活(無技術含量),所以先看一下要實現的效果,如果覺得閉著眼睛就能寫出來的,可以直接跳到本篇文章結尾為我辛勤的勞動點個贊,哈哈。
效果圖:
實現這個組合控件需要我們自定義屬性,寫一個類繼承ViewGroup并在構造方法中用代碼添加子View。所以,下面先自定義我們的屬性。
1. 自定義屬性
通過觀察上面的效果圖,我們發現我們共需要以下11個屬性:
- leftButtonText
- leftButtonTextColor
- leftButtonTextSize
- leftButtonImage:左側按鈕的圖片
- titleText
- titleColor
- titleSize
- rightButtonText
- rightButtonTextColor
- rightButtonTextSize
- rightButtonImage:右側按鈕的圖片
各個屬性的意思根據名稱就知道是什么意思,所以,我們就在資源文件attrs.xml來定義我們的屬性:
<declare-styleable name="Titlebar"> <attr name="leftButtonText" format="string|reference"></attr> <attr name="leftButtonTextColor" format="color|reference"></attr> <attr name="leftButtonTextSize" format="dimension|reference"></attr> <attr name="leftButtonImage" format="color|reference"></attr> <attr name="titleText" format="string|reference"></attr> <attr name="titleColor" format="color|reference"></attr> <attr name="titleSize" format="dimension|reference"></attr> <attr name="rightButtonText" format="string|reference"></attr> <attr name="rightButtonTextColor" format="color|reference"></attr> <attr name="rightButtonTextSize" format="dimension|reference"></attr> <attr name="rightButtonImage" format="color|reference"></attr> </declare-styleable>
注意:
- 我們可以attrs.xml的 <resources> 節點下面直接定義我們的屬性而不必在 <declare-styleable> 節點下面定義或引用,然后在布局文件中直接使用,但這種做法不推薦,因為將一些屬性添加到一個屬性集 <declare-styleable> 中便于管理和使用。
- 如果自定義屬性和系統屬性重名的時候,如果我們要定義屬性的類型和系統定義的一樣,那么我們可以直接在 <declare-styleable> 節點中引用系統的屬性,即添加一個 <attr> 節點但不要format屬性;
2. 繼承ViewGroup,完成控件的組合
觀察我們要實現的效果,發現使用ViewGroup的子類RelativeLayout可以很好和方便地完成。所以,新建一個類繼承RelativeLayout,重寫三個構造方法,在構造方法中先獲取布局中自定義屬性的值。
private void init(Context context,AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Titlebar); mLeftButtonText = typedArray.getString(R.styleable.Titlebar_leftButtonText); mLeftButtonTextColor = typedArray.getColor(R.styleable.Titlebar_leftButtonTextColor, Color.GRAY); mLeftButtonSize = typedArray.getDimension(R.styleable.Titlebar_leftButtonTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); mLeftButtonImage = typedArray.getDrawable(R.styleable.Titlebar_leftButtonImage); mTitleButtonText = typedArray.getString(R.styleable.Titlebar_titleText); mTitleButtonTextColor = typedArray.getColor(R.styleable.Titlebar_titleColor, Color.GRAY); mTitleButtonSize = typedArray.getDimension(R.styleable.Titlebar_titleSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); mRightButtonText = typedArray.getString(R.styleable.Titlebar_rightButtonText); mRightButtonTextColor = typedArray.getColor(R.styleable.Titlebar_rightButtonTextColor, Color.GRAY); mRightButtonSize = typedArray.getDimension(R.styleable.Titlebar_rightButtonTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); mRightButtonImage = typedArray.getDrawable(R.styleable.Titlebar_rightButtonImage); typedArray.recycle(); }
這里使用完TypedArray這個資源后要記得回收資源,就像使用完數據庫后要記得關閉連接和使用完IO流要記得關閉一樣。
獲取到了自定義屬性的值,那么,我們還需要通過代碼構建左側按鈕,中間標題,右側按鈕這三個控件:
private void initView(Context context) { if(mLeftButtonImage == null & mLeftButtonText != null){ // 當用戶沒有設置左側按鈕圖片并設置了左側的按鈕文本屬性時--添加左側文本按鈕 mLeftTextView = new TextView(context); mLeftTextView.setText(mLeftButtonText); mLeftTextView.setTextColor(mLeftButtonTextColor); mLeftTextView.setTextSize(mLeftButtonSize); RelativeLayout.LayoutParams leftParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); leftParams.addRule(RelativeLayout.CENTER_VERTICAL); addView(mLeftTextView, leftParams); }else if(mLeftButtonImage != null){ // 添加左側圖片按鈕 RelativeLayout.LayoutParams leftParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); leftParams.addRule(RelativeLayout.CENTER_VERTICAL); mLeftButton = new ImageView(context); mLeftButton.setImageDrawable(mLeftButtonImage); addView(mLeftButton, leftParams); } if(mTitleButtonText!=null){ // 添加中間標題 TextView titleTextView = new TextView(context); titleTextView.setText(mTitleButtonText); titleTextView.setTextColor(mTitleButtonTextColor); titleTextView.setTextSize(mTitleButtonSize); RelativeLayout.LayoutParams titleTextViewParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); titleTextViewParams.addRule(RelativeLayout.CENTER_IN_PARENT); addView(titleTextView,titleTextViewParams); } if(mRightButtonImage == null & mRightButtonText != null){ // 當用戶沒有設置右側按鈕圖片并設置了左側的按鈕文本屬性時--添加右側文本按鈕 mRightTextView = new TextView(context); mRightTextView.setText(mRightButtonText); mRightTextView.setTextColor(mRightButtonTextColor); mRightTextView.setTextSize(mRightButtonSize); RelativeLayout.LayoutParams rightParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rightParams.addRule(RelativeLayout.CENTER_VERTICAL); addView(mRightTextView,rightParams); }else if(mRightButtonImage != null){ // 添加右側圖片按鈕 RelativeLayout.LayoutParams rightParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rightParams.addRule(RelativeLayout.CENTER_VERTICAL); mRightButton = new ImageView(context); mRightButton.setImageDrawable(mRightButtonImage); addView(mRightButton, rightParams); } }
說明:由于左側和右側的按鈕既可以使用文字也可以使用圖片,所以,這里我使用了兩個控件代表這兩種情況,當用戶設置了左側按鈕圖片后就不會添加左側按鈕文本。
接下來我們還需要為左側和右側按鈕添加事件監聽,所以,我們先定義一個接口:
/** * 在button點擊事件接口 */ public interface OnButtonClickListener{ void onLeftClick(); void onRightClick(); }
設置按鈕監聽:
/** * 設置點擊事件 * @param onButtonClickListener */ public void setOnButtonClickListener(final OnButtonClickListener onButtonClickListener) { if(onButtonClickListener !=null){ if(mLeftTextView != null){ mLeftTextView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onButtonClickListener.onLeftClick(); } }); } if(mLeftButton != null){ mLeftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onButtonClickListener.onLeftClick(); } }); } if(mRightTextView != null){ mRightTextView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onButtonClickListener.onRightClick(); } }); } if(mRightButton != null){ mRightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onButtonClickListener.onRightClick(); } }); } } }
布局中使用我們的組合控件:
include_titlebar.xml
<?xml version="1.0" encoding="utf-8"?> <com.lt.titlebar.Titlebar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:lt="http://schemas.android.com/apk/res-auto" android:id="@+id/titlebar" android:layout_width="match_parent" android:layout_height="60dp" lt:leftButtonText="返回" lt:leftButtonTextColor="@android:color/white" lt:leftButtonTextSize="8sp" lt:titleText="標題" lt:titleColor="@android:color/white" lt:titleSize="8sp" lt:rightButtonText="完成" lt:rightButtonTextColor="@android:color/white" lt:rightButtonTextSize="8sp" android:background="#ea8010" android:padding="10sp" > </com.lt.titlebar.Titlebar>
注意:
- 命名空間的引入;
-
使用我們自定義的屬性可以使用4種情況的組合:
- 左側為文本按鈕,右側為文本按鈕;
- 左側為文本按鈕,右側為圖片按鈕;
- 左側為圖片按鈕,右側為文本按鈕;
- 左側為圖片按鈕,右側為圖片按鈕。
- 在需要上面類似的標題欄的時候,直接在布局中include引入這個布局文件即可,然后在activity或fragment或其他使用這個控件的地方在初始化這個控件并設置接口監聽即可。
在activity中初始化并設置接口監聽:
Titlebar titlebar = (Titlebar) findViewById(R.id.titlebar); titlebar.setOnButtonClickListener(new Titlebar.OnButtonClickListener() { @Override public void onLeftClick() { Toast.makeText(MainActivity.this,"左側按鈕被點擊了",0).show(); } @Override public void onRightClick() { Toast.makeText(MainActivity.this,"右側按鈕被點擊了",0).show(); } });
就是個體力活,鍛煉使用代碼創建并布局控件的能力,沒什么可總結的~