天天看點

淺析——ExpandableListView的使用

ExpandableListView(可擴充的ListView)

       ExpandableListVivew是ListView的子類,它在普通ListView的基礎上進行了擴充,它把應用中的清單項分為幾組,每組裡又可包含多個清單項。ExpandableListVivew的用法與普通ListView的用法非常相似,隻是ExpandableListVivew顯示的清單項應該由ExpandableAdapter提供。 

實作ExpandableAdapter的三種方式 

 一是擴充BaseExpandableListAdpter實作ExpandableAdapter。

 二是使用SimpleExpandableListAdpater将兩個List集合包裝成ExpandableAdapter

 三是使用simpleCursorTreeAdapter将Cursor中的資料包裝成SimpleCuroTreeAdapter

下圖為ExpandableListVivew支援的xml屬性

XML Attributes
屬性名 Related Method 描述
android:childDivider 指定各組内子類表項之間的分隔條 ①
android:childIndicator 顯示在子清單旁邊的Drawable對象②
android:childIndicatorLeft 子清單項訓示符的左邊限制位置③
android:childIndicatorRight 子清單項訓示符的右邊限制位置④
android:groupIndicator 顯示在組清單旁邊的Drawable對象⑤ 
android:indicatorLeft 組清單項訓示器的左邊限制位置⑥ 
android:indicatorRight 組清單項訓示器的右邊限制位置 ⑦

備注:

①   注:圖檔不會完全顯示,分離子清單項的是一條直線

②   注:可以是一個圖檔

③ 注:即從左端0位置開始計數,比如,假設訓示符是一個圖示,給定這個屬性值為

3dip,則表示從左端起3dip開始顯示此圖示。

④   注:表示右端到什麼位置結束

⑤   注:可以是一個圖檔。

⑥   注:表示左端從什麼位置開始。

⑦ 注:表示右端到什麼位置結束。

       一般适用于ExpandableListView的Adapter都要繼承BaseExpandableListAdapter這個類,并且必須重載getGroupView和getChildView這兩個最為重要的方法。

      當擴充BaseExpandableListAdapter時,關鍵是實作如下四個方法:

public abstract ViewgetChildView (int groupPosition, intchildPosition, boolean isLastChild, ViewconvertView, ViewGroup parent)

取得顯示給定分組給定子位置的資料用的視圖.

參數

groupPosition 包含要取得子視圖的分組位置.

childPosition   分組中子視圖(要傳回的視圖)的位置.

isLastChild     該視圖是否為組中的最後一個視圖.

convertView   如果可能,重用舊的視圖對象.使用前你應該保證視圖對象為非空,并且是否是合适的類型.如果該對象不能轉換為可以正确顯示資料的視圖,該方法就建立新視圖.不保證使用先前由getChildView(int, int,boolean, View, ViewGroup)建立的視圖.

parent     該視圖最終從屬的父視圖.

傳回

指定位置相應的子視圖.

public abstract intgetChildrenCount (int groupPosition)

取得指定分組的子元素數.

參數

groupPosition 要取得子元素個數的分組位置.

傳回

指定分組的子元素個數.

public abstract ViewgetGroupView (int groupPosition, booleanisExpanded, View convertView, ViewGroupparent)

取得用于顯示給定分組的視圖.這個方法僅傳回分組的視圖對象,要想擷取子元素的視圖對象,就需要調用getChildView(int, int, boolean, View, ViewGroup).

參數

groupPosition 決定傳回哪個視圖的組位置.

isExpanded     該組是展開狀态還是收起狀态 .

convertView   如果可能,重用舊的視圖對象.使用前你應該保證視圖對象為非空,并且是否是合适的類型.如果該對象不能轉換為可以正确顯示資料的視圖,該方法就建立新視圖.不保證使用先前由getGroupView(int, boolean,View, ViewGroup)建立的視圖.

parent     該視圖最終從屬的父視圖.

傳回

指定位置相應的組視圖.

public abstract intgetGroupCount ()

取得分組數.

傳回

分組數.

BaseExpandableListAdapter的重載的其它方法如下:

public abstract Object getChild(int groupPosition, int childPosition)

取得與指定分組、指定子項目關聯的資料.

參數

groupPosition 包含子視圖的分組的位置.

childPosition   指定的分組中的子視圖的位置.

傳回

與子視圖關聯的資料.

public abstract long getChildId(int groupPosition, intchildPosition)

取得給定分組中給定子視圖的ID.該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID).

參數

groupPosition 包含子視圖的分組的位置.

childPosition   要取得ID的指定的分組中的子視圖的位置.

傳回

與子視圖關聯的ID.

public abstract longgetCombinedChildId (long groupId, long childId)

取得一覽中可以唯一識别子條目的ID(包括分組ID和子條目ID).可擴充清單要求每個條目(分組條目和子條目)具有一個可以唯一識别清單中子條目和分組條目的ID.該方法根據給定子條目ID和分組條目ID傳回唯一識别ID.另外,如果hasStableIds()為真,該函數傳回的ID必須是固定不變的.

參數

groupId   包含子條目ID的分組條目ID.

childId    子條目的ID.

傳回

可以在所有分組條目和子條目中唯一識别該子條目的ID(可能是固定不變的).

public abstract longgetCombinedGroupId (long groupId)

取得一覽中可以唯一識别子條目的ID(包括分組ID和子條目ID).可擴充清單要求每個條目(分組條目和子條目)具有一個可以唯一識别清單中子條目和分組條目的ID.該方法根據給定子條目ID和分組條目ID傳回唯一識别ID.另外,如果hasStableIds()為真,該函數傳回的ID必須是固定不變的.

參數

groupId   分組條目ID.

傳回

可以在所有分組條目和子條目中唯一識别該分組條目的ID(可能是固定不變的).

public abstract Object getGroup(int groupPosition)

取得與給定分組關聯的資料.

參數

groupPosition 分組的位置.

傳回

指定分組的資料.

public abstract long getGroupId(int groupPosition)

取得指定分組的ID.該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID).

參數

groupPosition 要取得ID的分組位置.

傳回

與分組關聯的ID.

public abstract booleanhasStableIds ()

是否指定分組視圖及其子視圖的ID對應的背景資料改變也會保持該ID.

傳回

是否相同的ID總是指向同一個對象.

public abstract booleanisChildSelectable (int groupPosition, intchildPosition)

指定位置的子視圖是否可選擇.

參數

groupPosition 包含要取得子視圖的分組位置.

childPosition   分組中子視圖的位置.

傳回

是否子視圖可選擇.

注意:

在XML布局檔案中,如果ExpandableListView上一級視圖的大小沒有嚴格定義的話,則不能對ExpandableListView的android:layout_height屬性使用wrap_content值。(例如,如果上一級視圖是ScrollView的話,則不應該指定wrap_content的值,因為它可以是任意的長度。不過,如果ExpandableListView的上一級視圖有特定的大小的話,比如100像素,則可以使用wrap_content)

應用執行個體:

運作效果圖:

淺析——ExpandableListView的使用

項目結構圖:

淺析——ExpandableListView的使用
package com.jph.expandablelistviewdemo;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
 * Describe:</br>
 * 可擴充的ListView</br>
 * 本執行個體主要通過擴充BaseExpandableListAdapter來實作ExpandableListAdapter</br>
 * 并通過ExpandableListAdapter為ExpandableListView設定資料擴充卡</br>
 * 另外,本執行個體為ExpandableListView的子清單單擊事件設定監聽器* 
 * @author jph
 * Date:2014.07.14
 * */
public class ExpandableListViewDemo extends Activity {
	ExpandableListView list;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_expandable_list_view);
		list=(ExpandableListView)findViewById(R.id.list);
		//建立一個BaseExpandableListAdapter對象
		final ExpandableListAdapter adapter=new BaseExpandableListAdapter() {
			//設定組視圖的圖檔
            int[] logos = new int[] { R.drawable.js, R.drawable.mfzw,R.drawable.yczw};
            //設定組視圖的顯示文字
            private String[] category = new String[] { "僵屍	", "魔法植物", "遠端植物" };
            //子視圖顯示文字
            private String[][] subcategory = new String[][] {
                    {"旗幟僵屍", "铠甲僵屍", "書生見識", "鐵桶僵屍", "屍娃僵屍","舞蹈僵屍" },
                    { "黃金蘑菇", "貪睡蘑菇", "大頭蘑菇", "誘惑植物", "多嘴蘑菇","七彩蘑菇" },
                    { "滿天星", "風車植物", "帶刺植物", "貪睡植物","雙子植物","膽怯蘑菇" }

            };
            //子視圖圖檔
            public int[][] sublogos = new int[][] {
                    { R.drawable.js_1,R.drawable.js_2,R.drawable.js_3,
                      R.drawable.js_4,R.drawable.js_5,R.drawable.js_6},
                    { R.drawable.mfzw_1,R.drawable.mfzw_2,R.drawable.mfzw_3,
                      R.drawable.mfzw_4,R.drawable.mfzw_5,R.drawable.mfzw_6},
                    { R.drawable.yczw_1,R.drawable.yczw_2,R.drawable.yczw_3,
                      R.drawable.yczw_4,R.drawable.yczw_5,R.drawable.yczw_6 } };
            //定義一個顯示文字資訊的方法
            TextView getTextView(){
            	AbsListView.LayoutParams lp=new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,64);
            	TextView textView=new TextView(ExpandableListViewDemo.this);
            	//設定 textView控件的布局
            	textView.setLayoutParams(lp);
            	//設定該textView中的内容相對于textView的位置
            	textView.setGravity(Gravity.CENTER_VERTICAL);
            	//設定txtView的内邊距
            	textView.setPadding(36, 0, 0, 0);
            	//設定文本顔色
            	textView.setTextColor(Color.BLACK);
				return textView;           	
            	
            }
			@Override
			public boolean isChildSelectable(int groupPosition, int childPosition) {
				// TODO Auto-generated method stub
				return true;
			}
			
			@Override
			public boolean hasStableIds() {
				// TODO Auto-generated method stub
				return true;
			}
			//取得用于顯示給定分組的視圖. 這個方法僅傳回分組的視圖對象
			@Override
			public View getGroupView(int groupPosition, boolean isExpanded,
					View convertView, ViewGroup parent) {
				// TODO Auto-generated method stub
				//定義一個LinearLayout用于存放ImageView、TextView
				LinearLayout ll=new LinearLayout(ExpandableListViewDemo.this);
				//設定子控件的顯示方式為水準
				ll.setOrientation(0);
				//定義一個ImageView用于顯示清單圖檔
				ImageView logo=new ImageView(ExpandableListViewDemo.this);
				logo.setPadding(50, 0, 0, 0);
     			//設定logo的大小(50(padding)+46=96)
				AbsListView.LayoutParams lparParams=new AbsListView.LayoutParams(96,46);
				logo.setLayoutParams(lparParams);
				logo.setImageResource(logos[groupPosition]);
				ll.addView(logo);
				TextView textView=getTextView();
				textView.setTextSize(20);
				textView.setText(category[groupPosition]);
				ll.addView(textView);
				return ll;
			}
			//取得指定分組的ID.該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID).
			@Override
			public long getGroupId(int groupPosition) {
				// TODO Auto-generated method stub
				return groupPosition;
			}
			//取得分組數
			@Override
			public int getGroupCount() {
				// TODO Auto-generated method stub
				return category.length;
			}
			//取得與給定分組關聯的資料
			@Override
			public Object getGroup(int groupPosition) {
				// TODO Auto-generated method stub
				return category[groupPosition];
			}
			//取得指定分組的子元素數.
			@Override
			public int getChildrenCount(int groupPosition) {
				// TODO Auto-generated method stub
				return subcategory[groupPosition].length;
			}
			//取得顯示給定分組給定子位置的資料用的視圖
			@Override
			public View getChildView(int groupPosition, int childPosition,
					boolean isLastChild, View convertView, ViewGroup parent) {
				// TODO Auto-generated method stub
				//定義一個LinearLayout用于存放ImageView、TextView
				LinearLayout ll=new LinearLayout(ExpandableListViewDemo.this);
				//設定子控件的顯示方式為水準
				ll.setOrientation(0);
				//定義一個ImageView用于顯示清單圖檔
				ImageView logo=new ImageView(ExpandableListViewDemo.this);
				logo.setPadding(0, 0, 0, 0);
				//設定logo的大小
				LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(40, 40);
				logo.setLayoutParams(lp);
				logo.setImageResource(sublogos[groupPosition][childPosition]);
				ll.addView(logo);
				TextView textView=getTextView();
				textView.setText(subcategory[groupPosition][childPosition]);
				ll.addView(textView);
				return ll;
			}
			//取得給定分組中給定子視圖的ID. 該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID).
			@Override
			public long getChildId(int groupPosition, int childPosition) {
				// TODO Auto-generated method stub
				return childPosition;
			}
			
			@Override
			public Object getChild(int groupPosition, int childPosition) {
				// TODO Auto-generated method stub
				return subcategory[groupPosition][childPosition];
			}
		};
		list.setAdapter(adapter);		
		//為ExpandableListView的子清單單擊事件設定監聽器
		list.setOnChildClickListener(new OnChildClickListener() {			
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				// TODO Auto-generated method stub
				Toast.makeText(ExpandableListViewDemo.this, "你單擊了:"
						+adapter.getChild(groupPosition, childPosition), Toast.LENGTH_LONG).show();
				return true;
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.expandable_list_view, menu);
		return true;
	}

}
           

布局檔案:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
	<ExpandableListView android:id="@+id/list"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    ></ExpandableListView>a
</RelativeLayout>
           

繼續閱讀