Android:ExpandableListView使用
前言
- 每个child item有一个TextView和一个ImageView删除标识。
- 当点击一个child item,弹出Toast提示。
- child item可以通过点击删除图标来删除。
- 每次展开特定group时,其他group自动收缩。
Android实现
XML布局文件
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" > <ExpandableListView android:id="@+id/expandable_list_view_id" android:layout_width="match_parent" android:layout_height="match_parent" > </ExpandableListView> </RelativeLayout>
group_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffff" android:orientation="horizontal" android:gravity="center_vertical"> <TextView android:id="@+id/group_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:textColor="#808080" android:textSize="16sp" android:gravity="center_vertical" android:layout_alignParentLeft="true" android:text="@string/app_name"/> <ImageView android:id="@+id/group_indicator" android:src="@drawable/ic_guide_listview_down" android:contentDescription="@null" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="16sp" android:layout_alignParentRight="true"/> </RelativeLayout>
child_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/child_item_id" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" > <TextView android:id="@+id/child_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:paddingLeft="25dp" /> <ImageView android:id="@+id/child_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:contentDescription="@null" android:src="@drawable/delete" /> </RelativeLayout>
自定义Adapter
- 使用静态内部类标识父item和子item的weidget,因为这些控件的id是相同的,这样可以节省掉每次findViewById的时间。
- 重写(override)isChildSelectable方法,返回true,表示子item是可以点击的。
package com.example.expandtutorial; import java.util.ArrayList; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Typeface; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; public class CustomerAdapter extends BaseExpandableListAdapter{ private ArrayList<ParentObj> datas; private Context context; public CustomerAdapter(ArrayList<ParentObj> datas, Context context) { super(); this.datas = datas; this.context = context; } @Override public int getGroupCount() { return datas.size(); } @Override public int getChildrenCount(int groupPosition) { return datas.get(groupPosition).getChilds().size(); } @Override public Object getGroup(int groupPosition) { return datas.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return datas.get(groupPosition).getChilds().get(childPosition); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override // 是否有稳定的id,跟刷新顺序有关 public boolean hasStableIds() { return false; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { ParentViewHolder pviewHolder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.group_item, parent, false); pviewHolder = new ParentViewHolder(); pviewHolder.pTextView = (TextView) convertView.findViewById(R.id.group_text); pviewHolder.pImageView = (ImageView) convertView.findViewById(R.id.group_indicator); convertView.setTag(pviewHolder); } pviewHolder = (ParentViewHolder)convertView.getTag(); pviewHolder.pTextView.setTypeface(null, Typeface.BOLD); pviewHolder.pTextView.setText(datas.get(groupPosition).getpName()); if (isExpanded) { pviewHolder.pImageView.setImageResource(R.drawable.ic_guide_listview_up); } else { pviewHolder.pImageView.setImageResource(R.drawable.ic_guide_listview_down); } return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildViewHolder cViewHolder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.child_item, parent, false); cViewHolder = new ChildViewHolder(); cViewHolder.cTextView = (TextView)convertView.findViewById(R.id.child_item); cViewHolder.cImageView = (ImageView) convertView.findViewById(R.id.child_delete); convertView.setTag(cViewHolder); } cViewHolder = (ChildViewHolder)convertView.getTag(); cViewHolder.cTextView.setText(datas.get(groupPosition).getChilds().get(childPosition).getcName()); final int gPosition = groupPosition; final int cPosition = childPosition; cViewHolder.cImageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage("Do you want to remove?"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { datas.get(gPosition).getChilds().remove(cPosition); notifyDataSetChanged(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); } }); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } static class ParentViewHolder { TextView pTextView; ImageView pImageView; } static class ChildViewHolder { TextView cTextView; ImageView cImageView; } }
Activity
- ExpandableListView需要和自定义adapter进行绑定,通过setAdapter方法。
- 默认ExpandableListView带了一个指示箭头,我们自定义布局是不需要这个指示箭头的,可以使用expandableListView.setGroupIndicator(null);方法将其去掉。
- 设置setOnGroupExpandListener,当展开一个特定的group时,关闭其他group。
- 设置setOnChildClickListener,监听孩子点击事件。
package com.example.expandtutorial; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ExpandableListView.OnGroupExpandListener; import android.widget.Toast; public class MainActivity extends Activity { private ExpandableListView expandableListView; private CustomerAdapter customerAdapter; private ArrayList<ParentObj> listData = new ArrayList<ParentObj>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); createGroupData(); createChildData(); expandableListView = (ExpandableListView) findViewById(R.id.expandable_list_view_id); customerAdapter = new CustomerAdapter(listData, this); expandableListView.setAdapter(customerAdapter); expandableListView.setGroupIndicator(null); expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { for (int i = 0; i < customerAdapter.getGroupCount(); i ++) { if (i != groupPosition) { expandableListView.collapseGroup(i); } } } }); expandableListView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText(MainActivity.this, listData.get(groupPosition).getChilds().get(childPosition).getcName(), Toast.LENGTH_LONG).show(); return true; } }); } private void createGroupData() { ParentObj p1 = new ParentObj(); p1.setpName("HP"); listData.add(p1); ParentObj p2 = new ParentObj(); p2.setpName("DELL"); listData.add(p2); ParentObj p3 = new ParentObj(); p3.setpName("Lenovo"); listData.add(p3); ParentObj p4 = new ParentObj(); p4.setpName("Sony"); listData.add(p4); ParentObj p5 = new ParentObj(); p5.setpName("HCL"); listData.add(p5); ParentObj p6 = new ParentObj(); p6.setpName("Samsung"); listData.add(p6); } private void createChildData() { // preparing laptops collection(child) String[] hpModels = { "HP Pavilion G6-2014TX", "ProBook HP 4540", "HP Envy 4-1025TX" }; String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" }; String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series", "ThinkPad X Series", "Ideapad Z Series" }; String[] sonyModels = { "VAIO E Series", "VAIO Z Series", "VAIO S Series", "VAIO YB Series" }; String[] dellModels = { "Inspiron", "Vostro", "XPS" }; String[] samsungModels = { "NP Series", "Series 5", "SF Series" }; for (ParentObj p : listData) { if (p.getpName().equals("HP")) { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < hpModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(hpModels[i]); clists.add(cObj); } p.setChilds(clists); } else if (p.getpName().equals("DELL")) { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < dellModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(dellModels[i]); clists.add(cObj); } p.setChilds(clists); } else if (p.getpName().equals("Lenovo")) { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < lenovoModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(lenovoModels[i]); clists.add(cObj); } p.setChilds(clists); } else if (p.getpName().equals("Sony")) { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < sonyModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(sonyModels[i]); clists.add(cObj); } p.setChilds(clists); } else if (p.getpName().equals("HCL")) { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < hclModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(hclModels[i]); clists.add(cObj); } p.setChilds(clists); } else { ArrayList<ChildObj> clists = new ArrayList<ChildObj>(); for (int i = 0; i < samsungModels.length; i ++) { ChildObj cObj = new ChildObj(); cObj.setcName(samsungModels[i]); clists.add(cObj); } p.setChilds(clists); } } } } class ParentObj { private String pName; private ArrayList<ChildObj> childs = new ArrayList<ChildObj>(); public String getpName() { return pName; } public void setpName(String pName) { this.pName = pName; } public ArrayList<ChildObj> getChilds() { return childs; } public void setChilds(ArrayList<ChildObj> childs) { this.childs.clear(); this.childs.addAll(childs); } } class ChildObj { private String cName; public String getcName() { return cName; } public void setcName(String cName) { this.cName = cName; } }
源码
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。