Android 中关于ExpandableListView的简单使用,以一个demo为例,比较简单,主要用于理解一些概念性的知识。仅作为学习笔记。
1、定义:可扩展的ListView。
public class ExpandableListView extends ListView { ...... }
继承自ListView,因此基本使用方法同ListView:
(1)需要自定义一个继承自BaseExpandableListAdapter的Adapter;当然包括相关的布局等。
(2)注册监听事件;
由于该例子很简单,直接查看代码及注释,更清晰的显示常用方法的作用,在此不再详述。
2、基本用法:
//主界面布局: <Button android:id="@+id/expandBtn" android:textSize="18sp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/expandable_des" /> <ExpandableListView android:layout_marginTop="10dp" android:id="@+id/expandableListView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/bg_default" android:groupIndicator="@null" android:visibility="gone" ></ExpandableListView> <!-- android:groupIndicator="@null" 去掉系统自带的展开图标 -->
1 //自定义适配器ExpandAdapter.java 2 public class ExpandAdapter extends BaseExpandableListAdapter { 3 private final String TAG = "ExpandAdapter"; 4 5 private Context mContext; 6 private LayoutInflater layoutInflater; 7 8 private String[] groupNames = new String[] 9 {"C++","JAVA","Android","HTML"}; 10 11 // private Drawable leftDrawable; 12 private int arrowUpId,arrowDownId; 13 14 public ExpandAdapter(Context context) { 15 // TODO Auto-generated constructor stub 16 mContext = context; 17 layoutInflater = LayoutInflater.from(mContext); 18 19 arrowUpId = R.drawable.arrow_up; 20 arrowDownId = R.drawable.arrow_down; 21 22 // leftDrawable = context.getDrawable(R.drawable.ic_launcher); 23 // leftDrawable.setBounds(0, 0, leftDrawable.getMinimumWidth(), leftDrawable.getMinimumHeight()); 24 } 25 26 @Override 27 public Object getChild(int arg0, int arg1) { 28 // TODO Auto-generated method stub 29 return null; 30 } 31 32 @Override 33 public long getChildId(int arg0, int arg1) { 34 // TODO Auto-generated method stub 35 return arg1; 36 } 37 38 @Override 39 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View childView, 40 ViewGroup parent) { //子项布局 41 // TODO Auto-generated method stub 42 ChildHolder childHolder; 43 44 if(childView == null){ 45 childView = layoutInflater.inflate(R.layout.child_view, null); 46 childHolder = new ChildHolder(); 47 childHolder.child_content = (TextView) childView.findViewById(R.id.child_content); 48 childView.setTag(childHolder); 49 }else{ 50 childHolder = (ChildHolder) childView.getTag(); 51 } 52 53 // Log.d(TAG, "getChildView groupPos: " + groupPosition + " childPos: " + childPosition); 54 55 // if(groupPosition < groupNames.length){ 56 // groupHolder.name_type.setText(groupNames[groupPosition]); 57 // } 58 59 // if(childPosition % 2 == 0){ 60 // childHolder.child_content.setText("使用 drawableLeft getChildView getChildView getChildView getChildView"); 61 // childHolder.child_content.setCompoundDrawables(leftDrawable, null, null, null); 62 // } 63 64 return childView; 65 } 66 67 @Override 68 public int getChildrenCount(int arg0) { //子项总数 69 return 5; 70 } 71 72 @Override 73 public Object getGroup(int arg0) { 74 return groupNames[arg0]; 75 } 76 77 @Override 78 public int getGroupCount() { //一级列表项数 79 return groupNames.length; 80 } 81 82 @Override 83 public long getGroupId(int groupPosition) { 84 return groupPosition; 85 } 86 87 @Override 88 public View getGroupView(int groupPosition, boolean isExpand, View convertView, ViewGroup parent) {//一级列表项 89 // TODO Auto-generated method stub 90 GroupHolder groupHolder; 91 92 if(convertView == null){ 93 convertView = layoutInflater.inflate(R.layout.grounp_view, null); 94 groupHolder = new GroupHolder(); 95 groupHolder.img_type = (ImageView) convertView.findViewById(R.id.img_type); 96 groupHolder.name_type = (TextView) convertView.findViewById(R.id.name_type); 97 groupHolder.img_arrow = (ImageView) convertView.findViewById(R.id.img_arrow); 98 convertView.setTag(groupHolder); 99 }else{ 100 groupHolder = (GroupHolder) convertView.getTag(); 101 } 102 103 if(isExpand){ 104 // groupHolder.img_arrow.setImageResource(R.drawable.arrow_up); 105 groupHolder.img_arrow.setImageResource(arrowUpId); 106 }else{ 107 // groupHolder.img_arrow.setImageResource(R.drawable.arrow_down); 108 groupHolder.img_arrow.setImageResource(arrowDownId); 109 } 110 111 Log.i(TAG, "getGroupView groupPosition: " + groupPosition + " isExpand: " + isExpand); 112 113 if(groupPosition < groupNames.length){ 114 groupHolder.name_type.setText(groupNames[groupPosition]); 115 } 116 117 return convertView; 118 } 119 120 @Override 121 public boolean hasStableIds() { 122 return false; 123 } 124 125 //为了使子项响应点击事件,此处必须返回true!!!!!!!!!!!!!!!!!!!!!!!!!!! 126 @Override 127 public boolean isChildSelectable(int arg0, int arg1) { 128 // TODO Auto-generated method stub 129 return true; 130 } 131 132 class GroupHolder{ 133 ImageView img_type,img_arrow; 134 TextView name_type; 135 } 136 class ChildHolder{ 137 TextView child_content; 138 } 139 140 }
1 ExpandableListViewActivity中的基本使用: 2 3 expandableListView = (ExpandableListView) findViewById(R.id.expandableListView); 4 5 expandAdapter = new ExpandAdapter(this); 6 expandableListView.setAdapter(expandAdapter); 7 8 //注册监听事件: 9 private void initExpandableListener(){ 10 expandableListView.setOnGroupClickListener(new OnGroupClickListener() { 11 @Override 12 public boolean onGroupClick(ExpandableListView expandableListView, View arg1, int groupPosition, 13 long arg3) { //组(一级列表)点击事件 默认return false;若设为true,表示点击列表不会展开 14 // TODO Auto-generated method stub 15 Log.i(TAG, "onGroupClick " + groupPosition); 16 17 return false; 18 } 19 }); 20 expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() { 21 @Override 22 public void onGroupCollapse(int groupPosition) { //折叠 23 // TODO Auto-generated method stub 24 Log.i(TAG, "onGroupCollapse " + groupPosition); 25 26 } 27 }); 28 expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() { 29 @Override 30 public void onGroupExpand(int groupPosition) { //展开 若需要展开某项,其他项关闭,可在该处理方法中写入相应逻辑 31 // TODO Auto-generated method stub 32 Log.i(TAG, "onGroupExpand " + groupPosition); 33 34 } 35 }); 36 37 38 //Child 39 expandableListView.setOnChildClickListener(new OnChildClickListener() { 40 41 @Override 42 public boolean onChildClick(ExpandableListView arg0, View arg1, int groupPosition, 43 int childPosition, long arg4) { 44 // TODO Auto-generated method stub 45 Log.i(TAG, "onChildClick " + groupPosition + " " + childPosition); 46 47 return false; 48 } 49 }); 50 51 52 //添加一个按钮,用于测试expandGroup(int groupPos, boolean animate)中的animate不同值的显示效果. 53 Button expandBtn = (Button) findViewById(R.id.expandBtn); 54 expandBtn.setOnClickListener(new OnClickListener() { 55 @Override 56 public void onClick(View v) { 57 // TODO Auto-generated method stub 58 expandableListView.expandGroup(3, false); //展开时,是否执行滑动过程; 建议在测试时,选择展开后列表能够超出屏幕的,更容易看到两者不同 59 //看源码,发现为true时执行了方法smoothScrollToPosition(position, boundPosition) 60 //在默认情况下,点击group选项,系统也会执行上述smoothScrollToPosition方法. 61 62 } 63 }); 64 65 }
函数expandGroup(int groupPos, boolean animate)的执行效果:
默认界面 animate=false animate=true
3、注意事项:
a.写布局时,为了去掉系统自带的展开图标(上下箭头),需设置ExpandableListView的android:groupIndicator="@null"
b.可展开列表的适配器一般自定义,并继承自BaseExpandableListAdapter。当然,对于一些简单的数据或布局,可直接使用SimpleExpandableListAdapter或SimpleCursorTreeAdapter。
c.可以让Activity继承ExpandableListActivity,这样在Activity即可重写相关点击事件的方法.因为ExpandableListActivity实现了这些方法的接口。
d.若让子项响应点击事件,必须在ExpandAdapter中设置isChildSelectable()方法返回true。