ListView组件可以为用户提供列表的显示功能,但是如果想对这些列表数据进行分组管理,则需要使用android.widget.ExpandableListView组件完成。
与ListView组件一样,如果想要进行数据显示的设置,也需要一个适配器类,但是此时不再继承之前的BaseAdapter,而是继承BaseExpandableListAdapter类完成,此类为抽象类,所以要实现其中的所有抽象方法。
一、创建ExpandableListView
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());//展开分组事件
四个特有的事件监听。