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。
4、补充:
上述demo中的子项布局很简单,因为是简单的测试,所以只在布局中定义了一个TextView,图片使用了android:drawableLeft,在ExpandAdapter中可以看到还保留有在代码中设置图片的代码(注释的部分line),以下就总结以下用法:
//子项布局child_view.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="10dp" android:paddingBottom="10dp" > <TextView android:id="@+id/child_content" android:layout_width="wrap_content" android:layout_height="50dp" android:layout_marginStart="5dp" android:drawableLeft="@drawable/ic_launcher" android:ellipsize="end" android:gravity="center_vertical" android:text="child name" android:textSize="20sp" android:singleLine="true" android:maxLength="30" /> </LinearLayout>
总结:android中,若图标+文字确定的,则可使用TextView一个控件来实现,利用drawableLeft/drawableTop...等。但,若图标不确定,需要在代码中动态设置,则建议分开写,ImageView + TextView 。
因,在代码中设置图标很麻烦,需要以下三步:
(1) leftDrawable(获取Drawable对象)
(2) leftDrawable.setBounds(0, 0, leftDrawable.getMinimumWidth(), leftDrawable.getMinimumHeight());
(3) childHolder.child_content.setCompoundDrawables(leftDrawable, null, null, null);
来源:https://www.cnblogs.com/sparrowlhl/p/11236961.html