您好,登錄后才能下訂單哦!
需求:在黑馬做安全衛士的時候,功能9設置中心界面如下:
在點擊item的時候,復選框會反轉狀態,同時"自動更新已經關閉"會變換內容和顏色。
可以發現這個界面類似ListView,但又不是ListView,因為它的item數量是固定的,且最后一
item和之前的都不一樣。雖然這個看著像是標準的List結構,實則每個item不是完全一樣,因為
每個item的提示文本(如"自動更新已經關閉")的內容并不完全一樣。
假如用一般方式來布局的話,4個item就會有3*4 = 12個view,就會有多個findViewById()和
onClick事件。那么程序就會顯得十分的臃腫和冗余。
假如用ListView來布局的話,4個item就會有4個view,給item項添加item點擊事件即可。但是
上面已經說到,4個item并不是完全標準的ListView的item,每個item項的提示文本內容是獨立
的。如果一定要用ListView來實現的話,那么只要多聲明兩個數組來存放復選框兩種狀態各個
item的提示信息。雖然ListView也能實現想要的功能,但是有點大材小用的感覺,而且復用性差.
為了解決上面這一問題,于是自定義組合控件的技術出現了。
1. 什么是自定義組合控件
自定義組合控件,還不如說是自定義組合控件類。就是將多個控件封裝到一個容器里,將整個容
器看作一個控件。所有的控件還是用代碼,用相應的類來實現的。
■自定義組合控件的特點
1) 冗余度低
2)復用性強
2. 自定義組合控件的實現
將每個item看作一個自定義組合控件,它應該有title、desc_on、desc_off、check四個屬性。
將不同狀態的提示文本屬性信息封裝在控件里,這樣比較適于管理和控制。
1)設計自定義控件的布局
<?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="match_parent" android:background="#F0F0F0" > <!-- 標題 --> <TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:text="標題" android:textSize="20dp" android:textStyle="bold" /> <!-- 描述 --> <TextView android:id="@+id/tv_desc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_title" android:layout_below="@id/tv_title" android:layout_marginTop="5dp" android:text="描述" android:textSize="15dp" /> <!-- 復選框 --> <!-- 將下面的兩個屬性設置為false,可以屏蔽復選框的點擊事件。因為我想通過點擊整個自定義控件從而控制復選框的變化。 --> <!-- android:clickable="false" --> <!-- android:focusable="false" --> <CheckBox android:id="@+id/cb_check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="5dp" android:clickable="false" android:focusable="false" /> </RelativeLayout>
布局效果:
2)創建自定義控件類繼承布局
3)創建項目的自定義命名空間文件
■系統的命名空間
每個布局都要有 ,
其實這個屬性指向的是一個系統自帶的attr.xml文件,在系統的values文件夾目錄下,它指定了什么控件
會有什么屬性。
系統自帶的這個attr.xml文件里,定義了系統自帶的所有控件的屬性。
》系統attr.xml文件的根結點標簽
》比如ImageView控件
控件是用<declare-styleable>標簽來聲明的,用<attr>標簽指定控件的屬性。
■自定義的命名空間
》參照系統的自定義命名空間文件的格式,在自己的項目里values文件夾下新建一個
同樣名稱的attr.xml文件
可以在values目錄下新建attr.xml文件的時候,會自動提示根標簽resources,與
系統自帶的attr.xml文件格式一樣。
》》在新建的values/attr.xml文件里聲明自定義控件及其屬性
http://m.blog.csdn.net/blog/u011494050/44829267
Attribute "title" has already been defined - 姜家志
http://www.880688.com/program/osprojects/programdev/325300.htm
全局搜索包含title的.xml文件,發現V7包中support/v7/appcompat/res/values/attrs.xml中也有title屬性。
》》》在activity布局里加上自定義命名空間,引用自定義布局控件。
如果是使用依賴庫的自定義屬性,包名寫本App的包名,而不是依賴庫的包名
》》》》自定義控件的初始化
上面這種方式獲取自定義屬性需要對reference和xxx進行判斷,否則會發生異常。
另外一種獲取自定義屬性的方式:
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.RelativeHorizontalItemView); //得到自定義屬性 String leftText = (String) typedArray.getText(R.styleable.RelativeHorizontalItemView_leftText);
自定義控件內部定義的方法:
// 自定義兩個事件得到復選框的選中狀態和設置它的狀態 // 顯示 public boolean isCheck() { return cb_check.isChecked(); } // 設置 public void setCheck(boolean isChecked) { cb_check.setChecked(isChecked); updateCheck(); } // 更新復選框的狀態及配置文件中標記 public void updateCheck() { if (isCheck()) { tv_desc.setText(descOnValue); tv_desc.setTextColor(Color.GREEN); } else { tv_desc.setText(descOffValue); tv_desc.setTextColor(Color.RED); } //將狀態寫入標記 SPUtils.config_SetBooleanValue(getContext(), "autoUpdate", isCheck()); }
在activity里添加自定義控件點擊事件,完善邏輯:
//item1監聽事件 update_item.setOnClickListener(new MySettingCenterItemView.OnClickListener() { @Override public void onClick(View v) { /*定義自定義控件MySettingCenterItemView的時候,寫了兩個方法,就是因為不能直接訪問它的組合子控件。 通過方法就能獲取和設置它的組合子控件的屬性值了。 */ update_item.setCheck(!update_item.isCheck()); } });
拓展:
http://www.oschina.net/code/snippet_163910_6283
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。