ExpandableListView 有「群組 → 子項」兩層資料,過濾邏輯比 ListView 複雜。
class Group {
String name;
List children;
}
List originalData; // 完整資料
List filteredData; // 過濾後資料,傳給 Adapter
public void filter(String query) {
filteredData.clear();
if (TextUtils.isEmpty(query)) {
filteredData.addAll(originalData);
} else {
for (Group g : originalData) {
List matchedChildren = new ArrayList<>();
for (Child c : g.children) {
if (c.name.toLowerCase().contains(query.toLowerCase())) {
matchedChildren.add(c);
}
}
if (!matchedChildren.isEmpty()) {
Group newGroup = new Group(g.name, matchedChildren);
filteredData.add(newGroup);
}
}
}
notifyDataSetChanged(); // 刷新 UI
}
getGroupCount() 返回 filteredData.size()。getChildrenCount(groupPosition) 返回 filteredData.get(groupPosition).children.size()。getGroup/groupView、getChild/childView 皆從 filteredData 取值。
// 過濾前記錄展開群組
Set expandedPositions = new HashSet<>();
for (int i = 0; i < expandableListView.getExpandableListAdapter().getGroupCount(); i++) {
if (expandableListView.isGroupExpanded(i)) expandedPositions.add(i);
}
// 過濾後恢復
for (int pos : expandedPositions) {
if (pos < filteredData.size()) expandableListView.expandGroup(pos);
}
關鍵:**過濾生成新的雙層列表**,而非嘗試在原列表上隱藏 View,避免位置索引錯亂。