[Android基础] 使用 ExpandableListView 展现分类数据

这篇博客介绍了如何在Android应用中使用ExpandableListView来展示分类数据,通过创建特定的布局文件(group_view.xml和child_view.xml)以及自定义Adapter来实现。文章提到了QQ列表使用相同技术展示分组信息,并提供了简单的Activity代码示例,虽然没有深入到获取本机软件数据,但展示了基础用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       ExpandableListView虽然用的比较少,但是在数据分类的时相当有用,QQ列表就是用这个展现QQ分组信息,下面是小小的试用,效果图如下:


       先看看实现需要实现那些东西:

       1、需要主要的布局:main.xml

       2、需要一个显示父标题的布局:group_view.xml

       3、需要一个字显示子内容的布局:child_view.xml

       4、需要一个Activity显示

       5、需要写一个adapter

       【注】group_view.xml、child_view.xml 都可以实现复杂布局,如显示图片或者类似QQ,主要在adapter内代码处理即可

       

       接下来让我们看xml布局了解大概: main.xml 布局,只有一个ExpandableListView,简单,这里要注意id必须使用android内部已有id,如下面代码,不然会报错,原因可能是android ExpandableListView 不是内部一个基本部件,而是在其他view基础上添加修改,为节约内存在其基础上定制,可能会理解错欢迎指教!

<?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/android:list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"  />
    
</LinearLayout>

       group_view.xml也比较简单,如下,主要是显示文本,如果实现复杂布局可自己添加其他view,这里注意,为什么要paddingLeft。因为从图片我们都可以看到 ExpandableListView 前边有一个箭头的指示标志,如果不padding,或者margin的话,会产生重叠的情况出现,至少我是这样..

<?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" >
    
    <TextView 
        android:id="@+id/group_name"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:textSize="30sp"
        android:paddingLeft="50dip" />

</LinearLayout>

       下面是child_view.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="wrap_content"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/child_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp" />

</LinearLayout>

       接下来就是实现了,实现这里有一个需要理解,那就是数据来源,看因为父标题是一个数据集,子集合也是一个数据级别,所以用 ArrayList<String> groupList ,ArrayList<ArrayList<String>> childList 来存放,下面是adapter 实现代码:

public class BaseAdapter extends BaseExpandableListAdapter {
	
	private LayoutInflater inflater = null;
	private ArrayList<String> groupList = null; 
	private ArrayList<ArrayList<String>> childList = null;
	
	public BaseAdapter(Context context, ArrayList<String> groupList,
			ArrayList<ArrayList<String>> childList) {
		this.groupList = groupList;
		this.childList = childList;
		this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	@Override
	public Object getChild(int groupPosition, int childPosition) {
		return this.childList.get(groupPosition).get(childPosition);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;  // 可以自定义你子集的id
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		return this.childList.get(groupPosition).size();// 【备注】
	}

	@Override
	public Object getGroup(int groupPosition) {
		return this.groupList.get(groupPosition);
	}

	@Override
	public int getGroupCount() {
		return this.groupList.size();// 【备注】
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;  // 定义父列表id
	}

	@Override   // 子列表的显示
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		// 先判断,可以有效节约内存
		if(convertView == null) {
			convertView = this.inflater.inflate(R.layout.child_view, null);
		}
		TextView txtView = (TextView) convertView.findViewById(R.id.child_name);
		// 设置子标题
		txtView.setText(this.childList.get(groupPosition).get(childPosition));
		return convertView;
	}
	
	@Override  // 父列表的显示
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		
		if(convertView == null) {
			convertView = this.inflater.inflate(R.layout.group_view, null);
		}
		TextView txtView = (TextView) convertView.findViewById(R.id.group_name);
		// 设置父标题
		txtView.setText(this.groupList.get(groupPosition));
		return convertView;
	}

	@Override
	public boolean hasStableIds() {
		return false;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		// 设置可子列表点击
		return true;
	}
}
【备注】这里你先展现多少数据,对应的数量必须给到,不然会显示跟你预想中的不一样!

       下面是Activity,数据我就随便添加,本来想写获取本机软件来展现,谁知道自己懒了 哈哈,原理我们知道就ok啦,让Activity继承ExpandableListActivity,需要重写一系列方法,代码如下

public class ExpandablelistviewTestActivity extends ExpandableListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 父菜单
        ArrayList<String> groupList = new ArrayList<String>();
        groupList.add("第1个");
        groupList.add("第2个");
        groupList.add("第3个");
        groupList.add("第4个");
        groupList.add("第5个");
        // 子菜单
        ArrayList<ArrayList<String>> childList = new ArrayList<ArrayList<String>>();
        for(int i=1; i<groupList.size() + 1; i++) {
        	ArrayList<String> tmp = new ArrayList<String>();
        	tmp.add("第" + i + "-第1个");
        	tmp.add("第" + i + "-第2个");
        	tmp.add("第" + i + "-第3个");
        	childList.add(tmp);
        }
        // 设置数据适配器
        this.setListAdapter(new BaseAdapter(this, groupList, childList));
    }

	@Override
	public long getSelectedId() {
		Log.e("getSelectedId", super.getSelectedId() + "");
		return super.getSelectedId();
	}

	@Override
	public long getSelectedPosition() {
		Log.e("getSelectedPosition", super.getSelectedPosition() + "");
		return super.getSelectedPosition();
	}

	@Override
	public void onGroupCollapse(int groupPosition) {
		Log.e("onGroupCollapse", groupPosition + "");
		super.onGroupCollapse(groupPosition);
	}

	@Override
	public boolean setSelectedChild(int groupPosition, int childPosition,
			boolean shouldExpandGroup) {
		Log.e("setSelectedChild", childPosition + "");
		return super.setSelectedChild(groupPosition, childPosition, shouldExpandGroup);
	}

	@Override
	public void setSelectedGroup(int groupPosition) {
		Log.e("setSelectedGroup", groupPosition + "");
		super.setSelectedGroup(groupPosition);
	}

	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {
		Log.e("onChildClick", childPosition + "");
		return super.onChildClick(parent, v, groupPosition, childPosition, id);
	}

	@Override
	public void onGroupExpand(int groupPosition) {
		Log.e("onGroupExpand", groupPosition + "");
		super.onGroupExpand(groupPosition);
	}
}
【注】 Log.e 是为了更好看到日记内容,因为展现是红色的哈哈,个人习惯!

       大功告成,看看效果把 哈哈~

【附录】源代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值