標籤:android 下拉式清單 expandablelistview adapter 應用
1. ExpandableListView簡介
下拉式清單(可擴充的清單控制項)在App應用非常常見,在Android開發中是我們必須掌握的一個控制項,下面就來介紹一下ExpandableListView這個控制項的開發。
ExpandableListView分為組清單項目和子清單項目,單擊組清單項目,會顯示這組裡所有的子清單項目。和ListView一樣,它也是通過Adapter資料配接器完成資料與顯示的銜接,但它使用的另一種介面:ExpandableListAdapter.
今天我們要做的是實現一個繼承它的父介面:BaseExpandableListAdapter的類,來實現自訂的下拉式清單(就是如同ListView裡的方式,給它的清單項目設定介面布局檔案layout)。
2. 樣本
樣本包含四個檔案,兩個Java檔案和兩個layout檔案。Java檔案包含一個Activity,和我們自己實現的MyExpandAdapter;layout檔案一個是用於Activity,另一個就是子清單項目的介面布局檔案,至於組清單項目的布局,我們通過直接在代碼裡建立一個TextView來實現,這樣,就同時介紹了下拉式清單樣式實現的兩種方法。
plan_manager.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ExpandableListView android:id="@+id/expandableListView_plan_manager" android:layout_width="match_parent" android:layout_height="wrap_content" > </ExpandableListView></LinearLayout>
布局檔案,添加控制項
PlanManager.java
package com.plan;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.ExpandableListView;import android.widget.Toast;import com.example.plan.R;public class PlanManager extends Activity{ ExpandableListView sp_date_list = null; //列表 MyExpandAdapter adapter = null; //資料配接器 List<String> group_head; //組清單項目,每個組都有一個子List List<List<String>> child; //子清單項目 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.plan_manger); //擷取控制項 sp_date_list = (ExpandableListView)findViewById(R.id.expandableListView_plan_manager); //初始化組、子清單項目 group_head = new ArrayList<String>(); child = new ArrayList<List<String>>(); //設定適配器 sp_date_list.setAdapter(new MyExpandAdapter(this,group_head,child)); //設定資料配接器 sp_date_list.setCacheColorHint(0); //拖動列表的時候不出現黑色背景 addGroup("靜夜思"); addGroup("春曉"); addChild(0,"床前明月光"); addChild(0,"疑是地上霜"); addChild(1,"春眠不覺曉"); addChild(1,"處處聞啼鳥"); } //添加組清單項目 public void addGroup(String group){ group_head.add(group); child.add(new ArrayList<String>()); //child中添加新數組 } //添加對應組的自清單項目 public void addChild(int position,String child){ List<String> it = this.child.get(position); if(it != null){ it.add(child); }else{ it = new ArrayList<String>(); it.add(child); } } //子清單項目被選中的回應程式法 public void childSelect(int groupPosition,int childPosition){ Toast.makeText(getBaseContext(), Integer.toString(groupPosition)+":" + Integer.toString(childPosition), 2000).show(); }}
尋找控制項,串連顯示與適配器,並添加一些樣本資料,其中的addGroup和addChild以及childSelect可以提供給其他組件作為介面
plain_text.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/textView_plain_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /></LinearLayout>
這是子清單項目的布局檔案,因為只是簡單樣本,太複雜了的話學起來麻煩,所以只用了一個文字框,在實際項目中可以多加幾個控制項,改一下child的類型(最好改成map映射)就好
MyExpandAdapter.java
package com.plan;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.BaseExpandableListAdapter;import android.widget.TextView;import com.example.plan.R;public class MyExpandAdapter extends BaseExpandableListAdapter{ List<String> group_head; List<List<String>> child; PlanManager context; public MyExpandAdapter(Context content){ //初始化組、子清單項目 group_head = new ArrayList<String>(); child = new ArrayList<List<String>>(); } public MyExpandAdapter(PlanManager context,List<String> group_head, List<List<String>> child){ this.context = context; //初始化組、子清單項目 this.group_head = group_head; this.child = child; } @Override public int getGroupCount() { // TODO Auto-generated method stub return this.group_head.size(); } @Override public int getChildrenCount(int position) { // TODO Auto-generated method stub if(position<0||position>=this.child.size()) return 0; return child.get(position).size(); } @Override public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return group_head.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return child.get(childPosition).get(childPosition); } @Override public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return true; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { //擷取文本 String text = group_head.get(groupPosition); if(convertView == null){ //組列表介面只有一個文字框,直接產生 convertView = new TextView(context); //設定介面,AbsListView:用於實現條目的虛擬列表的基類 AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 60); ((TextView) convertView).setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); //文字框放在中央 convertView.setPadding(45, 0, 0, 0); //設定文本裡那個下拉的表徵圖遠一點 convertView.setLayoutParams(lp); Log.d("Group", text); } ((TextView) convertView).setText(text); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { //子清單控制項通過介面檔案設計 if(convertView ==null){//convert在運行中會重用,如果不為空白,則表明不用重新擷取 LayoutInflater layoutInflater;//使用這個來載入介面 layoutInflater = LayoutInflater.from(context); convertView = layoutInflater.inflate(R.layout.plain_text, null); } TextView tv = (TextView)convertView.findViewById(R.id.textView_plain_text); String text = child.get(groupPosition).get(childPosition); tv.setText(text); //擷取文本控制項,並設定值 return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { //調用Activity裡的ChildSelect方法 context.childSelect(groupPosition,childPosition); return true; }}
繼承介面後,Eclipse可以自動產生這些方法,我們只需要改一下就好。裡面有些地方用到了Log.d方法,用於在logcat裡輸出日誌(也可用System.out.println),主要是用來最佳化一下程式,通過看日誌列印了幾次,就可以看出程式中的方法是否有被重複調用。
【Android基礎篇】使用ExpandableListView實現自訂的下拉式清單