Android.自定义控件的实现 (转载)
尊重他人勞動(dòng)成果,轉(zhuǎn)載請(qǐng)注明出處。
轉(zhuǎn)自:http://kandy0619.blog.163.com/blog/static/64344345201012325939280/
可能是一直都在做Web的富客戶端開(kāi)發(fā)的緣故吧,在接觸Android之后,發(fā)現(xiàn)其控件實(shí)在慘不忍睹(不知道是否說(shuō)得過(guò)于偏激),我所說(shuō)的慘不忍睹的意思不是說(shuō)控件難看,Android的控件非常漂亮,這是我們公司公認(rèn)的,但是最大的缺點(diǎn)在于控件功能非常弱小。弱小得一個(gè)Radio只能放一個(gè)text,而沒(méi)有value(key)可以存放。這就是為什么我說(shuō)慘不忍睹的原因。
???????? 但是這不能怪google,畢竟才剛剛發(fā)展起來(lái),Android提供的只是一個(gè)最基本的控件實(shí)現(xiàn),而非一個(gè)完整、強(qiáng)大的實(shí)現(xiàn)。可幸的是,Android提供了自定義控件的實(shí)現(xiàn)。有了自定義控件,我們就可以再Android的基礎(chǔ)控件上實(shí)現(xiàn)我們想要的功能了。經(jīng)過(guò)一天的摸索,我終于實(shí)現(xiàn)了我第一個(gè)自定義的組合控件——RadioButton組合RadioGroup!
???????? 下面我將帶領(lǐng)大家進(jìn)入Android自定義控件的世界。如果覺(jué)得我的文章能夠幫助大家的話,請(qǐng)大方留下你的一些話語(yǔ)。因?yàn)槟銈兊牧粞允俏曳窒斫?jīng)驗(yàn)的精神源泉!謝謝!
???????? 1、設(shè)置自定義控件:Android自帶的RadioButton只能存放text,這不符合我們的需求,我們需要一個(gè)可以同時(shí)存放key-value對(duì)應(yīng)的鍵值。所以我們要編寫(xiě)一個(gè)自定義控件能存放key-value。
???????????????設(shè)計(jì)思路:新建一個(gè)類叫org.kandy.view.RadioButton,繼承自android.wedget.RadioButton,重寫(xiě)父類的所有構(gòu)造方法。這樣我們就實(shí)現(xiàn)了一個(gè)跟父類一摸一樣的控件。在此基礎(chǔ)上加入我們需要的功能:加入一個(gè)屬性value,用來(lái)存放RadioButton的key。
?????????????? 代碼如下:
1 public class RadioButton extends android.widget.RadioButton {2
3 private String mValue;
4
5 public RadioButton(Context context, AttributeSet attrs, int defStyle) {
6 super(context, attrs, defStyle);
7 }
8
9 public String getValue() {
10 return this.mValue;
11 }
12
13 public void setValue(String value) {
14 this.mValue = value;
15 }
16 public RadioButton(Context context, AttributeSet attrs) {
17 super(context, attrs);
18 try {
19 /**
20 * 跟values/attrs.xml里面定義的屬性綁定
21 */
22 TypedArray a = context.obtainStyledAttributes(attrs,
23 R.styleable.RadioButton);
24 this.mValue = a.getString(R.styleable.RadioButton_value);
25 a.recycle();
26 } catch (Exception e) {
27 e.printStackTrace();
28 }
29
30 }
31
32 public RadioButton(Context context) {
33 super(context);
34 }
35
36 }
?
?紅色代碼可以先不看。先看我們新加入的屬性value,由于Android習(xí)慣屬性命名以m開(kāi)頭。所以我們自定義控件就按照這個(gè)規(guī)則來(lái)寫(xiě)。不過(guò)對(duì)于setter、getter方法來(lái)說(shuō),不需要加入m。像上面的:屬性名稱mValue,setter:setValue(),getter:getValue()。當(dāng)然,你也可以不按照Android的習(xí)慣來(lái)命名。
??????? ?這樣,我們就可以使用這個(gè)自定義控件了。而且可以給它設(shè)置一個(gè)value,加上父類的text屬性。我們就可以在RadioButton中加入key-value的鍵值了。當(dāng)然,這里面的key對(duì)應(yīng)是控件的value屬性,value是對(duì)應(yīng)控件的text屬性。完了?沒(méi)有。自定義控件才剛開(kāi)始了。
?????????
????????? 2、XML中引用自定義控件
??????????在XML中加入自定義控件其實(shí)很簡(jiǎn)單。只需要在控件名字前加入包名即可。如下:
1 <org.kandy.view.RadioButton android:id="@id/isPayDepositTrue" fsms:value="true"2 android:layout_width="wrap_content" android:layout_height="wrap_content"
3 android:text="@string/yes" android:textSize="18sp">
4 </org.kandy.view.RadioButton>
?同樣,紅色部分可以先不看,也不需要加入到代碼中,這個(gè)時(shí)候加入會(huì)報(bào)錯(cuò),請(qǐng)注意。
????????
??????????3、attrs.xml屬性定義。
??????????在我們的思想中,既然我在自定義控件中加入了一個(gè)新的屬性,那么我就應(yīng)該能夠在xml中引用它,并對(duì)它賦初始值。我當(dāng)初也是這樣想的。可是卻無(wú)從下手。就是這一點(diǎn),折騰了我一個(gè)下午。
?????????? 正解:res/values/attrs.xml中定義屬性,在自定義控件中獲取這個(gè)屬性,然后跟自定義控件的屬性相綁定。
??????????????? attrs.xml如果沒(méi)有,就新建一個(gè)。這里只存放自定義控件中需要的屬性,在我看來(lái),這個(gè)文件是一個(gè)中介,負(fù)責(zé)將layout/xx.xml里面的對(duì)這個(gè)變量的引用和自定義控件里面的屬性綁定起來(lái)。
???????????????? attrs.xml完整代碼如下:
1 <?xml version="1.0" encoding="utf-8"?>2 <resources>
3 <declare-styleable name="RadioButton"><!-- 控件名稱-->
4 <attr name="value" format="string"/><!-- 屬性名稱,類型-->
5 </declare-styleable>
6 </resources>
如果res下沒(méi)有錯(cuò)誤的話,在R中應(yīng)該就會(huì)生成這些資源的id。這樣我們就能在自定義控件中引用他們。
?
?????????? 4、控件屬性與XML定義綁定。
?????????? 這下子我們又回到了自定義控件的編寫(xiě)上來(lái)了。先看看我們?cè)诘谝稽c(diǎn)提到的紅色字體部分。這一部分就是實(shí)現(xiàn)控件屬性與XML定義綁定的代碼。
1 /**2 * 跟values/attrs.xml里面定義的屬性綁定
3 */
4 TypedArray a = context.obtainStyledAttributes(attrs,
5 R.styleable.RadioButton);
6 this.mValue = a.getString(R.styleable.RadioButton_value);
7 a.recycle();
?TypedArray其實(shí)就是一個(gè)存放資源的Array,首先從上下文中獲取到R.styleable.RadioButton這個(gè)屬性資源的資源數(shù)組。attrs是構(gòu)造函數(shù)傳進(jìn)來(lái),應(yīng)該就是對(duì)應(yīng)attrs.xml文件。a.getString(R.styleable.RadioButton_value);這句代碼就是獲取attrs.xml中定義的屬性,并將這個(gè)屬性的值傳給本控件的mValue.最后,返回一個(gè)綁定結(jié)束的信號(hào)給資源:a.recycle();綁定結(jié)束。
?
????????????? 5、在xml中對(duì)控件賦初始值。
???????????? 請(qǐng)看第2點(diǎn),綁定結(jié)束后可以在需要賦初始值的地方賦值。
1 <ScrollView android:layout_width="fill_parent"2 android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:fsms=http://schemas.android.com/apk/res/org.kandy>
4
5 <org.kandy.view.RadioButton android:id="@id/isPayDepositTrue" fsms:value="true"
6 android:layout_width="wrap_content" android:layout_height="wrap_content"
7 android:text="@string/yes" android:textSize="18sp">
8 </org.kandy.view.RadioButton>
9
10 </ScrollView>
?紅色部分首先聲明命名空間。命名空間為fsms.路徑是http://schemas.android.com/apk/res/這一部分是不變的,后面接的是R的路徑:org.kandy.R。然后在自定義控件的xml描述中就可以這樣使用fsms:value="true"。這樣就實(shí)現(xiàn)了自定義控件的初始化賦值。
?
?????????????6、RadioGroup、RadioButton組合控件的實(shí)現(xiàn)
????????????????? 上面是自定義控件的實(shí)現(xiàn),下面將要說(shuō)的是組合控件的實(shí)現(xiàn)。在組合控件中,最經(jīng)常用到的應(yīng)該就是RadioGroup和RadioButton。RadioButton的實(shí)現(xiàn)已經(jīng)在上面介紹了。下面要介紹RadioGroup的自定義控件和功能擴(kuò)展:
????????????????????代碼如下:
1 public class RadioGroup extends android.widget.RadioGroup {2
3 private String mValue;
4
5 public RadioGroup(Context context, AttributeSet attrs) {
6 super(context, attrs);
7 }
8
9 public RadioGroup(Context context) {
10 super(context);
11 }
12 // 設(shè)置子控件的值
13 public void setChildValue(){
14 int n = this.getChildCount();
15 for(int i=0;i<n;i++){
16 final RadioButton radio = (RadioButton)this.getChildAt(i);
17 if(radio.getValue().equals(this.mValue)){
18 radio.setChecked(true);
19 }else{
20 radio.setChecked(false);
21 }
22 }
23 }
24 // 獲取子類的值
25 public void getChildValue(){
26 int n = this.getChildCount();
27 for(int i=0;i<n;i++){
28 RadioButton radio = (RadioButton)this.getChildAt(i);
29 if(radio.isChecked()){
30 this.mValue=radio.getValue();
31 }
32 }
33 }
34
35 public void setValue(String value) {
36 this.mValue = value;
37 setChildValue();
38 }
39
40 public String getValue(){
41 getChildValue();
42 return this.mValue;
43 }
44 }
? RadioGroup只做兩件事:獲取子控件(RadioButton)所選擇的值;設(shè)置子控件要選擇的值。
?????????? 方法非常簡(jiǎn)單,循環(huán)或者RadioGroup的子控件,檢測(cè)哪個(gè)控件被checked,然后getValue,將此value賦值給RadioGroup的擴(kuò)展屬性value。在這里不多說(shuō)了。相信大家都能看懂。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/nanhuchongzi/archive/2012/03/29/2422914.html
總結(jié)
以上是生活随笔為你收集整理的Android.自定义控件的实现 (转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 梦到铁公鸡是什么意思
- 下一篇: 梦到女性朋友代表什么