Android ExpandableListView和ScrollView联用的一些注意事项
之前有整理过ScrollView嵌套ListView的例子,讲的是计算listview的每一项的高度。已达到目标效果。同样的ExpandableListView嵌套ScrollView也是这么个思路,不过要稍微加一些方法和稍微做一些改动。
要实现这个功能首先要准备三个基础的方法:
一、计算ExpandableListView的group项的高度的方法(即计算listview合并时的高度的方法)备注:ExpandableListView是listview的子类所以,listview的方法它同样可以使用
/** 动态改变listView的高度 */ public void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); // params.height = 80 * (listAdapter.getCount() - 1); // params.height = 80 * (listAdapter.getCount()); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); ((MarginLayoutParams) params).setMargins(0, 0, 0, 0); listView.setLayoutParams(params); }
二、计算ExpandableListView展开时group下的子view列表的高度的方法
/** * 可扩展listview展开时调用 * * @param listView * @param groupPosition */ public static void setExpandedListViewHeightBasedOnChildren( ExpandableListView listView, int groupPosition) { ExpandableListAdapter listAdapter = listView.getExpandableListAdapter(); if (listAdapter == null) { return; } View listItem = listAdapter.getChildView(groupPosition, 0, true, null, listView); listItem.measure(0, 0); int appendHeight = 0; for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) { appendHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); // Log.d(TAG, "Expand params.height" + params.height); params.height += appendHeight; listView.setLayoutParams(params); }
三、计算ExpandableListView合并时消除group下的子view列表的高度的方法
/** * 可扩展listview收起时调用 * * @param listView * @param groupPosition */ public static void setCollapseListViewHeightBasedOnChildren( ExpandableListView listView, int groupPosition) { ExpandableListAdapter listAdapter = listView.getExpandableListAdapter(); if (listAdapter == null) { return; } View listItem = listAdapter.getChildView(groupPosition, 0, true, null, listView); listItem.measure(0, 0); int appendHeight = 0; for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) { appendHeight += listItem.getMeasuredHeight(); } /*Log.d(TAG, "Collapse childCount=" + listAdapter.getChildrenCount(groupPosition));*/ ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height -= appendHeight; listView.setLayoutParams(params); }
三个计算方法都贴出来了,下面来看看这三个方法到底是怎样使用的
一、在设置ExpandableListView的adapter的时候计算一下它合并时的宽度,并显示出来。(这一步是初始化)
例如:
listView.setAdapter(adapter);
ListUtil.getInstance().setListViewHeightBasedOnChildren(listView);
二、当ExpandableListView展开时调用计算方法
例如:
/** * 当ExpandableListView展开时调用 */ listView.setOnGroupExpandListener(new OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { /* * Log.e("expand", "扩展"); for (int i = 0; i < 4; i++) { if * ((groupPosition != i) && listView.isGroupExpanded(i)) { * listView.collapseGroup(i); } } */ /** * 计算group下的子项的高度 */ ListUtil.setExpandedListViewHeightBasedOnChildren(listView, groupPosition); // 更新group每一项的高度 ListUtil.getInstance().setListViewHeightBasedOnChildren( listView); } });
三、当ExpandableListView合并时调用计算方法
例如:
/** * 当ExpandableListview收缩时调用 */ listView.setOnGroupCollapseListener(new OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { Log.e("collapse", "收缩"); /* * 计算group下的每一个子项的高度,然后收缩 */ ListUtil.setCollapseListViewHeightBasedOnChildren(listView, groupPosition); /* * 重新评估group的高度 */ ListUtil.getInstance().setListViewHeightBasedOnChildren( listView); /* * ListUtil.setCollapseListViewHeightBasedOnChildren(listView, * groupPosition); */ } });
好了,到这里就结束了。备注:在计算方发中的adapter中的layout外层布局不能是RelativeLayout,否则将会报空指针。具体什么原因我就不说了,晚上一大堆的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探