這節(jié)我們主要講解自定義View的其中的三個(gè)步驟:設(shè)計(jì)我們的所需的屬性、實(shí)現(xiàn)我們的View和在xml中引用我們的View,注重為什么這樣設(shè)計(jì)的思想。
首先,我們要了解google是怎么實(shí)現(xiàn)一個(gè)控件的,比如我們最熟悉的LinearLayout,我們使如何使用它的呢?我們會(huì)在XML文件中定義一個(gè)LinearLayout,再為它寫(xiě)上相應(yīng)的屬性,比如:android:layout_width 和android:layout_height等,這樣我們就可以使用LinearLayout,如下圖:

但是google使如何定義它的源文件的呢?就是為什么這樣寫(xiě)就可以使用一個(gè)控件。我們知道LinearLayout是繼承ViewGroup,它重寫(xiě)了ViewGroup的一些方法來(lái)滿(mǎn)足自己的一些需求,但是這些屬性又是從哪里來(lái)的呢,我們可以從android源碼的attrs.xml文件中可以看到下面幾句話(huà):

我們首先需要一個(gè)atts.xml文件,用來(lái)配置我們所需要的屬性,然后我們需要重寫(xiě)控件來(lái)滿(mǎn)足自己的要求,最后一步就是在xml文件使用我們的控件。下面以一個(gè)小案例具體實(shí)現(xiàn)以上自定義控件的步驟,實(shí)現(xiàn)效果圖文章最后圖。
我們?cè)撛趺醋?/h4>
-
設(shè)計(jì)我們所需要的屬性
這里我們將TobBar分為三個(gè)部分,中間顯示標(biāo)題,還有左右button。為標(biāo)題我們?cè)O(shè)計(jì)了 標(biāo)題的顏色,大小和文本,為左右button設(shè)計(jì)了button顏色,button文本和背景顏色屬性。
-
實(shí)現(xiàn)我們的“View”
這里TobBar繼承自RelativeLayout ,代碼如下:
設(shè)計(jì)我們所需要的屬性

這里我們將TobBar分為三個(gè)部分,中間顯示標(biāo)題,還有左右button。為標(biāo)題我們?cè)O(shè)計(jì)了 標(biāo)題的顏色,大小和文本,為左右button設(shè)計(jì)了button顏色,button文本和背景顏色屬性。
實(shí)現(xiàn)我們的“View”
這里TobBar繼承自RelativeLayout ,代碼如下:
public class TopBar extends RelativeLayout {
private Button leftButton, rightButton;
private TextView tvTitle;
private int leftTextColor;
private Drawable leftBackgroung;
private String leftText;
private int rightTextColor;
private Drawable rightBackgroung;
private String rightText;
private float titleTextSize;
private int titleTextColor;
private String title;
private RelativeLayout.LayoutParams leftParsms,rightParsms,titleParams;
//下面我們就需要將上面的是三個(gè)控件放進(jìn)我們的ViewGroup中去
//實(shí)例化左按鈕的布局屬性
leftParsms = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//設(shè)置左按鈕靠左顯示
leftParsms.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
//將左按鈕添加到本自定義控件中
addView(leftButton,leftParsms);
//同上
rightParsms = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
rightParsms.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
addView(rightButton,rightParsms);
titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
addView(tvTitle,titleParams);
}
}
* 引用我們View
我們首先看一下怎么使用一個(gè)系統(tǒng)控件的,TextView為例,如下代碼:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
由上面設(shè)置一個(gè)系統(tǒng)控件為例,我們可以得知,首先我們要聲明一個(gè)控件名稱(chēng),接著下面便是 android:來(lái)引用一個(gè)屬性,并給它賦值。其實(shí)這個(gè)android就是布局文件頭部的引用文件,即下面一行代碼:
xmlns:android="http://schemas.android.com/apk/res/android"
所以我們根據(jù)系統(tǒng)為例來(lái)引用我們自定義的組件。
使用自定義的控件的屬性首先添加命名空間,如下:
xmlns:custom="http://schemas.android.com/apk/res-auto"
其中custom可以任意指定,但不能與系統(tǒng)的命名空間相同,在android studio中如上 用res-auto,在eclipse中res后需要完整的包名。引用自定義控件代碼如下:
<com.example.mytopbar.TopBar
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="40dp"
custom:leftBackground="#16c7ca"
custom:leftText="Back"
custom:leftTextColor="#FFFFFF"
custom:rightBackground="#16c7ca"
custom:rightText="More"
custom:rightTextColor="#FFFFFF"
custom:title="自定義標(biāo)題"
custom:titleTextColor="#123412"
custom:titleTextSize="10sp">
</com.example.mytopbar.TopBar>
---
**注:這里有個(gè)地方需要注意一下,就是AS中Button默認(rèn)大寫(xiě)問(wèn)題。如果在布局文件中添加一個(gè)Button組件**
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="100sp"
android:text="aaaaa"
android:textSize="20sp" />
**結(jié)果如下圖:**

**本來(lái)我們?cè)O(shè)置的text屬性為“aaaaa”,但是結(jié)果確實(shí)大寫(xiě)“AAAAA”,這是因?yàn)閍ndroid主題Theme.AppCompat中,在5.0以上的API的時(shí)候,Button的默認(rèn)屬性是字母全部大寫(xiě)。解決方案:**
* 使用5.0以下的API,則不會(huì)有這個(gè)問(wèn)題
* 在不想大寫(xiě)的控件中添加屬性(關(guān)閉全部大寫(xiě)屬性):
android:textAllCaps="false"
(目測(cè)自定義的組件便沒(méi)有這個(gè)屬性,只能用第一種方法或者下面的一種方法)
* 如果在其他控件中,比如我們上面的自定義組件中有自定的屬性--leftText、rightText,在該組件中就沒(méi)有上面所說(shuō)的textAllCaps屬性,那么我們也可以在values-->style.xml文件中style塊內(nèi)添加下面一行代碼:
<item name="android:textAllCaps">false</item>
這樣我們就可以把所有的組件都不會(huì)自動(dòng)大寫(xiě)
---
做完以上的工作,我們TopBar的靜態(tài)部分已經(jīng)完成,如下圖:

下面實(shí)現(xiàn)Button的點(diǎn)擊事件,就不在詳述了,讀者可以自行實(shí)現(xiàn)一些點(diǎn)擊事件。本文最后附上工程源碼(其實(shí)是一個(gè)Android UI模板設(shè)計(jì)的源碼),里面簡(jiǎn)單的實(shí)現(xiàn)了一些點(diǎn)擊事件,讀者可以自行理解。
**[工程源碼](http://download.csdn.net/detail/cs9426478/9652456)**