Android实战简易教程-第十一枪(树形组件:ExpandableListView显示和动态添加删除)

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());//展开分组事件

四个特有的事件监听。

喜欢的朋友可以点个赞关注我!谢谢

时间: 2024-09-30 15:47:33

Android实战简易教程-第十一枪(树形组件:ExpandableListView显示和动态添加删除)的相关文章

Android实战简易教程-第二十二枪(基于Baas的用户注册功能)

基于Baas实现用户的注册功能. 我们使用Bmob提供的API进行实战开发,首先在Bmob官网上下载SDK,然后将jar包拷入工程内. 创建应用,获取应用key: 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:

Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉加载实现!)

上一节我们实现了数据表的加载,但是,当数据表数据很多时,我们就要考虑数据的分页,这里我们选用了PullToRefreshListView控件,先看一下该控件的说明: 效果图:                                 正在刷新                                                                       刷新后        一.导入Library 下载源码后(https://github.com/chrisba

Android实战简易教程-第二十八枪(Uri转String型实例)

接上一篇文章.我们能够轻易的获取所选图片的uri,那么我们考虑怎样将获取的uri转换成String型的地址呢? 接下来我们通过实例来研究.布局文件和上篇(二十七枪)一致,我们就不再列出,直接看MainActivity.java: package com.example.userphoto; import java.io.File; import android.app.Activity; import android.content.Intent; import android.database

Android实战简易教程-第十六枪(LineChart实现数据趋势展示)

aChartEngine中的line Chart是线图,是数据显示的一种.首先我们要下载aChartEngine的jar包,然后导入到工程中. 直接看一下代码(部分注释): package com.yayun.linechart; import java.util.ArrayList; import java.util.List; import org.achartengine.ChartFactory; import org.achartengine.chart.PointStyle; imp

Android实战简易教程-第十五枪(实现ListView中Button点击事件监听)

1.main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" androi

Android实战简易教程-第二十九枪(基于Face++实现年龄识别APP(一))

我们通过Face++提供的api和服务实现HowOld App的开发.首先我们实现图片的选择功能. 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:la

Android实战简易教程-第十八枪(ViewPager组件详解)

对于ViewPager组件我们知道: 1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类. 2)ViewPager类需要一个PagerAdapter适配器类给它提供数据. 3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用. 下面我们通过实例看一下ViewPager的使用. 一 实现V

Android实战简易教程-第十枪(画廊组件Gallery实用研究)

Gallery组件用于拖拽浏览图片,下面我们就来看一下如何实现. 一.实现Gallery 1.布局文件很简单: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/MyLayout" android:lay

Android实战简易教程-第二十六枪(基于ViewPager实现微信页面切换效果)

1.头部布局文件top.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="40dp" an