在旧版 Android 界面中使用 ExpandableListView
426 字
2 分钟
在旧版 Android 界面中使用 ExpandableListView
目标
在需要维护传统 View 界面的项目中,用 ExpandableListView 展示省份与城市两级列表,不再继承已弃用的 ExpandableListActivity。
适用范围
ExpandableListView 适合维护既有两级列表。新项目如果需要更灵活的交互、动画或多层数据,优先考虑 RecyclerView 或 Jetpack Compose 的可展开列表模式。

添加布局
<?xml version="1.0" encoding="utf-8"?>
<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/expandable_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
准备数据和适配器
private final String[] provinces = {
"山西省", "吉林省", "河北省", "山东省"
};
private final String[][] cities = {
{"太原市", "吕梁市", "长治市"},
{"长春市", "松原市", "吉林市"},
{"石家庄市", "唐山市", "承德市"},
{"菏泽市", "青岛市", "济南市"}
};
核心适配器实现如下。示例复用 convertView,避免滚动时重复创建视图:
class RegionAdapter extends BaseExpandableListAdapter {
@Override
public int getGroupCount() {
return provinces.length;
}
@Override
public int getChildrenCount(int groupPosition) {
return cities[groupPosition].length;
}
@Override
public Object getGroup(int groupPosition) {
return provinces[groupPosition];
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return cities[groupPosition][childPosition];
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(
int groupPosition,
boolean isExpanded,
View convertView,
ViewGroup parent
) {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(
android.R.layout.simple_expandable_list_item_1,
parent,
false
);
}
TextView label = convertView.findViewById(android.R.id.text1);
label.setText(provinces[groupPosition]);
return convertView;
}
@Override
public View getChildView(
int groupPosition,
int childPosition,
boolean isLastChild,
View convertView,
ViewGroup parent
) {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(
android.R.layout.simple_expandable_list_item_2,
parent,
false
);
}
TextView label = convertView.findViewById(android.R.id.text1);
label.setText(cities[groupPosition][childPosition]);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
绑定列表
ExpandableListView list = findViewById(R.id.expandable_list);
list.setAdapter(new RegionAdapter());

验证
确认每个分组可展开和收起,子项数量与数据一致,并在快速滚动后检查文字没有错位。若数据有稳定主键,应返回真实主键并将 hasStableIds() 改为 true。
参考
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
在旧版 Android 界面中使用 ExpandableListView
https://blog.mintalix.com/posts/study-android-expand-list/相关文章智能推荐
1
使用 Activity Result API 获取页面返回结果
android-development用 AndroidX Activity Result API 替代 startActivityForResult,完成结果注册、页面启动、数据返回与生命周期验证。
2
排查 Android 深色主题下的标题栏冲突
android-development说明 windowActionBar 与 windowNoTitle 的真实作用,并给出在深色主题中排查重复标题栏和主题继承问题的方法。
3
从 Kotlin synthetic 迁移到 View Binding
android-development解释 Kotlin Android Extensions synthetic 视图访问为何消失,并使用官方支持的 View Binding 完成替代。
4
二叉树中序遍历:递归与显式栈
algorithms从左、根、右的访问顺序出发,实现二叉树中序遍历,并比较递归与显式栈两种写法的边界和复杂度。
5
最小路径和:压缩二维动态规划
algorithms从只能向右或向下移动的约束推导最小路径和状态转移,并将二维状态表压缩为一维数组。
随机文章随机推荐


