ExpandableListView是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组又可包含多少个列表项。
ExpandableListVIew的用法与普通ListView的用法非常相似,只是ExpandableListView所显示的列表项应该由ExpandListAdapter提供。ExpandListAdapter也是一个接口,下图展示了该接口的继承关系。
与Adapter类似的是,实现ExpandableListAdapter也有如下三种常用方式。
- 扩展BaseExpandableListAdapter实现ExpandableListAdapter
- 使用SimpleExpandableListAdapter将两个List集合包装成ExpandableListAdapter。
- 使用SimpleCursorTreeAdapter将Cursor中的数据包装成SimpleCursorTreeeAdapter。
下面的程序示范了如何通过自定义的ExpandableListAdapter为ExpandableListView提供列表项。
该程序的布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" > <ExpandableListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
后台文件如下:
package org.crazyit.helloworld; import android.os.Bundle; import android.app.Activity; 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.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class ExpandableListViewTest extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.expandable_list_view_test); //创建一个BaseExpandableListAdapter对象 ExpandableListAdapter adapter=new BaseExpandableListAdapter(){ int[] logos=new int[]{ R.drawable.p, R.drawable.z, R.drawable.t }; private String[] armTypes=new String[]{"神族兵种", "虫族兵种", "人族兵种"}; private String[][] arms=new String[][]{ {"狂战士","龙骑士","黑暗圣堂","电兵"}, {"小狗","刺蛇","飞龙","自爆飞机"}, {"机枪兵","护士MM","幽灵"} }; @Override public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return arms[groupPosition][childPosition]; } @Override public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } private TextView getTextView(){ AbsListView.LayoutParams lp=new AbsListView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,64); TextView textView=new TextView(ExpandableListViewTest.this); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); textView.setPadding(70, 0, 0, 0); textView.setTextSize(20); return textView; } //该方法决定每个子选项的外观 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { // TODO Auto-generated method stub TextView textView=getTextView(); textView.setText(getChild(groupPosition,childPosition).toString()); return textView; } @Override public int getChildrenCount(int groupPosition) { // TODO Auto-generated method stub return arms[groupPosition].length; } @Override public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return armTypes[groupPosition]; } @Override public int getGroupCount() { // TODO Auto-generated method stub return armTypes.length; } @Override public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } //该方法决定每个组选项的外观 @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LinearLayout ll=new LinearLayout(ExpandableListViewTest.this); ll.setOrientation(0); ImageView logo=new ImageView(ExpandableListViewTest.this); logo.setImageResource(logos[groupPosition]); ll.addView(logo); TextView textView=getTextView(); textView.setText(getGroup(groupPosition).toString()); ll.addView(textView); return ll; } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return true; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { // TODO Auto-generated method stub return true; } }; ExpandableListView expandListView=(ExpandableListView)findViewById(R.id.list); expandListView.setAdapter(adapter); } @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_test, menu); return true; } }
上面程序中的关键代码就是扩展BaseExpandableListAdapter来实现ExpandableListAdapter,当扩展BaseExpandableListAdapter时,关键是实现如下4个方法。
- getGroupCount():该方法返回包含的组列表项的数量。
- getGroupView():该方法返回的View对象将作为组列表项。
- getChildrenCount():该方法返回特定组所包含的的子列表项的数量。
- getChildView():该方法返回的View对象将作为特定组、特定位置的子列表项。
上面的程序中getChildView()方法返回一个普通TextView,因为每个列表项都是一个普通文本框。而getGroupView方法则返回一个LinearLayout对象,该LinearLayout对象里包含一个ImgeView和TextView。因此每个组列表项都由图片和文本组成。
运行上面的程序将看到如下效果: