ListView组件可以为用户提供列表的显示功能,但是如果想对这些列表数据进行分组管理,则需要使用android.widget.ExpandableListView组件完成。
与ListView组件一样,如果想要进行数据显示的设置,也需要一个适配器类,但是此时不再继承之前的BaseAdapter,而是继承BaseExpandableListAdapter类完成,此类为抽象类,所以要实现其中的所有抽象方法。
1.定义适配器类-MyExpandableListAdapter.java
package org.yayun.demo; import android.content.Context; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseExpandableListAdapter; import android.widget.TextView; public class MyExpandableListAdapter extends BaseExpandableListAdapter { public String[] groupStrings = { "我的好友", "我的家人", "同事", "狐朋狗友" }; public String[][] childStrings = { { "瓜瓜", "太湖", "老皮", "磨叽" }, { "大姐", "肥肥", "二姐", "爸爸" }, { "张工", "程序猿" }, { "大鹏", "二妞" } }; private Context context; MyExpandableListAdapter(Context context) { this.context = context; } public int getGroupCount() {// 自动覆写 return this.groupStrings.length; } public int getChildrenCount(int groupPosition) {// 自动覆写 return childStrings[groupPosition].length; } public Object getGroup(int groupPosition) {// 自动覆写 return groupStrings[groupPosition]; } public Object getChild(int groupPosition, int childPosition) {// 自动覆写 return childStrings[groupPosition][childPosition]; } public long getGroupId(int groupPosition) {// 自动覆写 return groupPosition; } public long getChildId(int groupPosition, int childPosition) {// 自动覆写 return childPosition; } public boolean hasStableIds() {// 自动覆写 return true; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {// 自动覆写 TextView textView = buildTextView(); textView.setText(this.getGroup(groupPosition).toString()); return textView; } private TextView buildTextView() { AbsListView.LayoutParams params = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 35);// 指定布局参数 TextView textView = new TextView(this.context);// 创建TextView textView.setLayoutParams(params);// 设置布局参数 textView.setTextSize(15.0f); textView.setGravity(Gravity.LEFT);// 左对齐 textView.setPadding(40, 8, 3, 3);// 间距 return textView; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {// 自动覆写 TextView textView = buildTextView(); textView.setText(getChild(groupPosition, childPosition).toString()); return textView; } public boolean isChildSelectable(int groupPosition, int childPosition) {// 自动覆写 return true; } }
2.定义布局文件:
<?xml version="1.0" encoding="utf-8"?> <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/elistview" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
3.定义MainActivity.java:
package org.yayun.demo; import android.app.Activity; import android.database.DataSetObserver; import android.os.Bundle; import android.view.ContextMenu; import android.view.View; import android.view.ViewGroup; import android.view.ContextMenu.ContextMenuInfo; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.Toast; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ExpandableListView.OnGroupClickListener; import android.widget.ExpandableListView.OnGroupCollapseListener; import android.widget.ExpandableListView.OnGroupExpandListener; public class MainActivity extends Activity { private ExpandableListView expandableListView; private ExpandableListAdapter adapter; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 生命周期方法 super.setContentView(R.layout.main); // 设置要使用的布局管理器 expandableListView=(ExpandableListView)findViewById(R.id.elistview); adapter=new MyExpandableListAdapter(this); expandableListView.setAdapter(adapter); super.registerForContextMenu(this.expandableListView);//注册上下文菜单 /* * 下面四个监听是其特有的 */ expandableListView.setOnChildClickListener(new OnChildClickListenerImpl());//子项单击事件 expandableListView.setOnGroupClickListener(new OnGroupClickListenerImpl());//组项单击事件 expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListenerImpl());//关闭分组事件 expandableListView.setOnGroupExpandListener(new OnGroupExpandListenerImpl());//展开分组事件 } private class OnChildClickListenerImpl implements OnChildClickListener{ public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText(MainActivity.this, "子项被选中,groupPosition="+groupPosition+"childPosition="+childPosition, Toast.LENGTH_SHORT).show(); return false; } } private class OnGroupClickListenerImpl implements OnGroupClickListener{ public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { Toast.makeText(MainActivity.this, "组项被选中,groupPosition="+groupPosition, Toast.LENGTH_SHORT).show(); return false; } } private class OnGroupCollapseListenerImpl implements OnGroupCollapseListener{ public void onGroupCollapse(int groupPosition) { Toast.makeText(MainActivity.this, "分组关闭,groupPosition="+groupPosition, Toast.LENGTH_SHORT).show(); } } private class OnGroupExpandListenerImpl implements OnGroupExpandListener{ public void onGroupExpand(int groupPosition) { Toast.makeText(MainActivity.this, "分组展开,groupPosition="+groupPosition, Toast.LENGTH_SHORT).show(); } } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ExpandableListView.ExpandableListContextMenuInfo info=(ExpandableListView.ExpandableListContextMenuInfo)menuInfo; } }
4.运行实例:
结合List的add()和remove()方法实现动态添加和删除操作。
1.定义适配器类:
package org.yayun.demo; import java.util.List; import android.app.Activity; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseExpandableListAdapter; import android.widget.TextView; //为expandable list view 提供内容的基类 public class InfoDetailsAdapter extends BaseExpandableListAdapter { Activity activity; List<String> group; List<List<String>> child; public InfoDetailsAdapter(Activity a, List<String> group, List<List<String>> child) { activity = a; this.group = group; this.child = child; } // child method stub public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub // System.out.println("*******************"+child.get(groupPosition).get(childPosition)); return child.get(groupPosition).get(childPosition); } public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } public int getChildrenCount(int groupPosition) { // TODO Auto-generated method stub return child.get(groupPosition).size(); } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { // TODO Auto-generated method stub String string = child.get(groupPosition).get(childPosition); return getGenericView(string); } // group method stub public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return group.get(groupPosition); } public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } public int getGroupCount() { // TODO Auto-generated method stub return group.size(); } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { // TODO Auto-generated method stub String string = group.get(groupPosition); return getGenericView(string); } // View stub to create Group/Children 's View public TextView getGenericView(String s) { // Layout parameters for the ExpandableListView AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 64); TextView text = new TextView(activity); text.setLayoutParams(lp); // Center the text vertically text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); // Set the text starting position text.setPadding(36, 0, 0, 0); text.setText(s); return text; } public boolean hasStableIds() { // TODO Auto-generated method stub return false; } public boolean isChildSelectable(int groupPosition, int childPosition) { // TODO Auto-generated method stub return true; } }
2.main.xml:
<p><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="<a target=_blank href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>" android:id="@+id/layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" ></p><p> <ExpandableListView android:id="@+id/expandList" android:layout_width="fill_parent" android:layout_height="wrap_content" /></p><p></LinearLayout></p>
3.add.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" /> <EditText android:id="@+id/add_name" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="电话:" /> <EditText android:id="@+id/add_phone" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="性别:" /> <EditText android:id="@+id/add_sex" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="住址:" /> <EditText android:id="@+id/add_home" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/add_ok" android:layout_width="90dip" android:layout_height="wrap_content" android:text="OK" /> <Button android:id="@+id/add_no" android:layout_width="90dip" android:layout_height="wrap_content" android:text="NO" /> </LinearLayout> </LinearLayout>
4.delete.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ID:" /> <EditText android:id="@+id/delete_id" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/delete_ok" android:layout_width="90dip" android:layout_height="wrap_content" android:text="OK" /> <Button android:id="@+id/delete_no" android:layout_width="90dip" android:layout_height="wrap_content" android:text="NO" /> </LinearLayout> </LinearLayout>
5.MainActivity.java:
package org.yayun.demo; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.Dialog; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ExpandableListView; import android.widget.Toast; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ExpandableListView.OnGroupClickListener; public class MainActivity extends Activity { public final static int MENU_ADD = Menu.FIRST; public final static int MENU_DELETE = Menu.FIRST + 1; ExpandableListView expandList; InfoDetailsAdapter adapter; Activity activity; List<String> group; List<List<String>> child; // 初始化group child内容 public void initialData() { group = new ArrayList<String>(); child = new ArrayList<List<String>>(); addInfo("肥肥", new String[] { "234", "two 1", "three 1" }); addInfo("肥蛋", new String[] { "one 2", "two 2", "three 2" }); addInfo("垃圾肥", new String[] { "one 3", "two 3", "three 3" }); } public void addInfo(String p, String[] c) { group.add(p); List<String> item = new ArrayList<String>(); for (int i = 0; i < c.length; i++) { item.add(c[i]); } child.add(item); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); activity = this; expandList = (ExpandableListView) findViewById(R.id.expandList); // 初始化各级元素 initialData(); // 适配器内容 adapter = new InfoDetailsAdapter(this, group, child); expandList.setAdapter(adapter); expandList.setOnGroupClickListener(new OnGroupClickListener() { public boolean onGroupClick(ExpandableListView arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub System.out.println("The row id of the group clicked" + arg3); Toast.makeText(activity, "[Group Click]:" + arg2, Toast.LENGTH_SHORT).show(); return false; } }); expandList.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2, int arg3, long arg4) { // TODO Auto-generated method stub Toast.makeText(activity, "[Child Click]:" + arg2 + ":" + arg3, Toast.LENGTH_SHORT).show(); return false; } }); } // 下述2个函数处理Menu按钮的事件 public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub menu.add(0, MENU_ADD, 0, " 添加 "); menu.add(0, MENU_DELETE, 0, " 删除 "); return super.onCreateOptionsMenu(menu); } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_ADD: Log.i("", "FRIEND_ID"); createDialogAdd(); dialogAdd.show(); break; case MENU_DELETE: Log.i("", "FRIEND_ID"); createDialogDelete(); dialogDelete.show(); break; } return super.onOptionsItemSelected(item); } EditText add_name, add_phone, add_sex, add_home; EditText delete_id; Button add_ok, add_no; Button delete_ok, delete_no; Dialog dialogAdd, dialogDelete; public void createDialogAdd() {//创建对话框 Log.i("", "createDialogAdd"); View viewAdd = this.getLayoutInflater().inflate(R.layout.add, null); dialogAdd = new Dialog(this); dialogAdd.setContentView(viewAdd); dialogAdd.setTitle("输入新成员信息"); add_name = (EditText) viewAdd.findViewById(R.id.add_name); add_phone = (EditText) viewAdd.findViewById(R.id.add_phone); add_sex = (EditText) viewAdd.findViewById(R.id.add_sex); add_home = (EditText) viewAdd.findViewById(R.id.add_home); add_ok = (Button) viewAdd.findViewById(R.id.add_ok); add_no = (Button) viewAdd.findViewById(R.id.add_no); add_ok.setOnClickListener(new OnClickListener() {//点击确定 public void onClick(View v) { // TODO Auto-generated method stub String[] data = { add_phone.getText().toString(), add_sex.getText().toString(), add_home.getText().toString() }; addInfo(add_name.getText().toString(), data); dialogAdd.dismiss(); adapter.notifyDataSetChanged(); } }); add_no.setOnClickListener(new OnClickListener() {//取消 public void onClick(View v) { // TODO Auto-generated method stub dialogAdd.dismiss(); } }); } public void createDialogDelete() {//创建删除按钮 View viewDelete = this.getLayoutInflater().inflate(R.layout.delete, null); dialogDelete = new Dialog(this); dialogDelete.setContentView(viewDelete); dialogDelete.setTitle("删除指定成员"); delete_id = (EditText) viewDelete.findViewById(R.id.delete_id); delete_ok = (Button) viewDelete.findViewById(R.id.delete_ok); delete_no = (Button) viewDelete.findViewById(R.id.delete_no); delete_ok.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub String id = delete_id.getText().toString(); if (!id.equals("")) { int i = Integer.parseInt(id); group.remove(i); child.remove(i); dialogDelete.dismiss(); adapter.notifyDataSetChanged(); } } }); delete_no.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub dialogDelete.dismiss(); } }); } }
运行实例如下:
expandableListView.setOnChildClickListener(new OnChildClickListenerImpl());//子项单击事件
expandableListView.setOnGroupClickListener(new OnGroupClickListenerImpl());//组项单击事件
expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListenerImpl());//关闭分组事件
expandableListView.setOnGroupExpandListener(new OnGroupExpandListenerImpl());//展开分组事件
四个特有的事件监听。
喜欢的朋友可以点个赞关注我!谢谢
Android实战简易教程-第十一枪(树形组件:ExpandableListView显示和动态添加删除)
原文地址:http://blog.csdn.net/yayun0516/article/details/46388307