Android中Listview(四)--分組listview
阿新 • • 發佈:2019-02-13
分組的應用場合還是很多的,有資料集合的地方往往要分組顯示;
分組的形式也很多,最常見的就是鑲嵌在列表中,網上說的很多ExpandListView的也是一種。
Android自帶的通訊錄中的聯絡人是按照拼音首字母(A,B,C,D......)分組分類的,效果如下:
我們今天也是要實現這樣類似的一個效果。
分組的形式也很多,最常見的就是鑲嵌在列表中,網上說的很多ExpandListView的也是一種。
Android自帶的通訊錄中的聯絡人是按照拼音首字母(A,B,C,D......)分組分類的,效果如下:
我們今天也是要實現這樣類似的一個效果。
1.樣本資料:
為了突出重點,直擊要點,這裡提供一個整理好的資料樣本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//list:資料集合
private
List<String> list = new
ArrayList<String>(); //listTag:Tag集合,其中Tag是分類的分割標籤,每個分組的header
private
List<String> listTag = new
ArrayList<String>();
public
void setData(){
list.add( "A" );
listTag.add( "A" );
for ( int i= 0 ;i< 3 ;i++){
list.add( "阿凡達" +i);
}
list.add( "B" );
listTag.add( "B" );
for ( int i= 0 ;i< 3 ;i++){
list.add( "位元風暴" +i);
}
list.add( "C" );
listTag.add( "C" );
for ( int i= 0 ;i< 30 ;i++){
list.add( "查理風雲" +i);
}
}
|
2.Activity佈局準備:
放置一個listView來呈現資料。
group_list_activity.xml:
1 2 3 4 5 6 7 8 9 10 11 12 |
<? xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!--簡單的列表顯示-->
< ListView android:id="@+id/group_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"/>
</ LinearLayout >
|
3.自定義Adapter(本文繼承ArrayAdapter):
這個是本文的重點和核心。
Adapter介面為資料和介面搭建了一個訪問的橋樑,最重要的就是getView()方法,用這個方法我們可以實現一定程度的介面自定義。
ArrayAdapter間接實現了Adapter介面,這裡我們簡單起見,資料來源只是提供單一的String陣列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private
static class GroupListAdapter extends ArrayAdapter<String>{
//存放標籤的列表,用來判斷資料項的型別
//如果資料項在標籤列表中,則是標籤項,否則是資料項
private List<String> listTag = null ;
public GroupListAdapter(Context context, List<String> objects, List<String> tags) {
super (context, 0 , objects);
this .listTag = tags;
}
@Override
public View getView( int position, View convertView, ViewGroup
parent) {
... ....
}
}
|
我們來看看getView方法:
?1 2 3 4 |
//該方法根據adapter的順序一行一行的組織列表
//其中position表示第幾行,也就是當前行在adapter的位置,
//convertView表示第幾行的View
View getView( int position, View convertView, ViewGroup parent);
|
現在我們就是要重寫getView方法,來實現列表中嵌入分組標籤。
分組標籤也是列表資料項之一,也是被一行一行的畫上去的,但是它和其他資料項UI是不一致的,所以我們需要準備2套資料項佈局模板:
資料項模板group_list_item.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<? xml version="1.0" encoding="utf-8"?>
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dip">
<!-- 圖片和文字 -->
<!-- 隨便放了一張圖片,稍微美化一下 -->
< ImageView
android:src="@drawable/list_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
< TextView
android:id="@+id/group_list_item_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="5dip"
android:gravity="center_vertical"/>
</ LinearLayout >
|
標籤項模板group_list_item_tag.xml:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!-- 只有文字,但是高度小店,背景色設定為555555灰色 -->
<? xml version="1.0" encoding="utf-8"?>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#555555"
android:paddingLeft="10dip">
< TextView
android:id="@+id/group_list_item_text"
android:layout_width="wrap_content"
android:layout_height="20dip"
android:textColor="#ffffff"
android:gravity="center_vertical"/>
</ LinearLayout >
|
好,我們現在把這兩個模板應用到getView方法中去:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Override
public
View getView( int
position, View convertView, ViewGroup parent) {
View view = convertView;
//根據標籤型別載入不通的佈局模板
if (listTag.contains(getItem(position))){
//如果是標籤項
view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null );
} else {
//否則就是資料項了
view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null );
}
//顯示名稱
TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);
textView.setText(getItem(position));
//返回重寫的view
return view;
}
|
4.禁止標籤項的響應事件:
在ArrayAdapter的父類BaseAdapter中提供了isEnable的()方法,我們看看這個方法:
1 2 3 4 |
//預設情況,如果這個方法不是分割符,返回true
//分隔符是無選中和無點選事件的
//說白了,你想不想把改position項當做分隔符,想的話就返回false,否則返回true
public
boolean isEnabled ( int position)
|
這個方法剛好用來禁用標籤項的響應事件。具體實現如下:
?1 2 3 4 5 6 7 |
@Override
public
boolean isEnabled( int position) {
if (listTag.contains(getItem(position))){
return false ;
}
return super .isEnabled(position);
}
|
現在標籤項不會再有任何觸控效果了,猶如一塊死木板。
5.完整程式碼:
整個Activity和Adapter程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
public
class GroupListActivity extends Activity {
private GroupListAdapter adapter = null ;
private ListView listView = null ;
private List<String> list = new ArrayList<String>();
private List<String> listTag = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.group_list_activity);
setData();
adapter = new GroupListAdapter( this ,
list, listTag);
listView = (ListView)findViewById(R.id.group_list);
listView.setAdapter(adapter);
}
public void setData(){
list.add( "A" );
listTag.add( "A" );
for ( int i= 0 ;i< 3 ;i++){
list.add( "阿凡達" +i);
}
list.add( "B" );
listTag.add( "B" );
for ( int i= 0 ;i< 3 ;i++){
list.add( "位元風暴" +i);
}
list.add( "C" );
listTag.add( "C" );
for ( int i= 0 ;i< 30 ;i++){
list.add( "查理風雲" +i);
}
}
private static class
GroupListAdapter extends
ArrayAdapter<String>{
private List<String> listTag = null ;
public GroupListAdapter(Context context, List<String> objects, List<String> tags) {
super (context, 0 , objects);
this .listTag = tags;
}
@Override
public boolean isEnabled( int position)
{
if (listTag.contains(getItem(position))){
return false ;
}
return super .isEnabled(position);
}
@Override
public View getView( int position, View convertView, ViewGroup
parent) {
View view = convertView;
if (listTag.contains(getItem(position))){
view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null );
} else {
view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null );
}
TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);
textView.setText(getItem(position));
return view;
}
}
}
|
6.最終效果: