我认为没有任何内置方法可以使用内置 Android 功能来完成您尝试的操作。为了进行一些测试,我从 Android API 示例 (C:\<android-sdk-directory>\samples\android-15\ApiDemos\src\com\example\android\apis\view\ExpandableList3.java) 中的代码开始。
我使用了ExpandableListView.CHOICE_MODE_SINGLE。选择模式适用于选中或选择的任何View。 (ExpandableListView 源代码说它决定了一次可以选择多少项,但在ListView 中,它似乎适用于选中。)请注意,文档说在单选模式下,您无法从 getCheckedItemPosition 获得有效的结果以获取 ListView。这似乎是真的。
我的测试表明ExpandableListActivity 不会自动选中或选中被点击/触摸的项目,也不会自动将焦点放在被点击的子项上。只有 ExpandableListActivityitself 和持有该子项的组在您单击其中一个子项后会自动聚焦。
这是我的一些代码(大部分来自 Android 示例):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final String NAME = "NAME";
final String IS_EVEN = "IS_EVEN";
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
for (int i = 0; i < 12; i++) {
Map<String, String> curGroupMap = new HashMap<String, String>();
groupData.add(curGroupMap);
curGroupMap.put(NAME, "Group " + i);
curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
List<Map<String, String>> children = new ArrayList<Map<String, String>>();
for (int j = 0; j < 12; j++) {
Map<String, String> curChildMap = new HashMap<String, String>();
children.add(curChildMap);
curChildMap.put(NAME, "Child " + j);
curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
}
childData.add(children);
}
SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
this,
groupData,
android.R.layout.simple_expandable_list_item_1,
new String[] {NAME, IS_EVEN},
new int[] {android.R.id.text1, android.R.id.text2},
childData,
R.layout.child,
new String[] {NAME, IS_EVEN},
new int[] {android.R.id.text1, android.R.id.text2}
);
ExpandableListView expListView = (ExpandableListView)findViewById(android.R.id.list);
setListAdapter(adapter);
expListView.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE);
expListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expListView, View viewClicked, int groupPosition, int childPosition, long childRowId) {
viewClicked.setSelected(true); // the only way to force a selection of the clicked item
请注意最后一行,它强制点击的孩子处于选中状态。然后,您可以使用带有 Drawable 状态列表的 XML selector 来突出显示选中的项目。 (这并不完全有效 - 更多内容如下。)
在我的ExpandableListActivity 中的onChildClick 内部,我做了一些测试,发现如下:
groupPosition; // index of group within the ExpandableListViewActivity
childRowId; // for my particular ExpandableListView, this was the index of the child in the group
childPosition; // for my particularExpandableListView, this was also the index of the child in the group
expListView.getCheckedItemPosition(); // null - from ListView class
expListView.getSelectedView(); // null - from AbsListView class
expListView.getSelectedItemId(); // a long, based on the packed position - from AdapterView class
expListView.getSelectedId(); // -1 - from ExpandableListView class, calls getSelectedPosition()
expListView.getSelectedPosition(); // -1 - from ExpandableListView class, calls getSelectedItemPosition()
expListView.getSelectedItemPosition(); // -1 - from AdapterView class
expListView.getFocusedChild(); // null - from ViewGroup class
expListView.getItemIdAtPosition(1); // a long (View ID) - from AdapterView class
viewClicked.isFocused()); // false
viewClicked.isPressed()); // false
viewClicked.isSelected()); // true only if we explicitly set it to true
expListView.isFocused()); // true
expListView.isPressed()); // false
expListView.isSelected()); // false
expListView.getCheckedItemPosition())); // -1 - from ListView
expListView.getSelectedId())); // -1 - from ExpandableListView
/* expListView.getChildAt(childPosition) is not helpful, because it looks at the rendered
LinearLayout with a bunch of TextViews inside it to get the index and find the child,
and you won't generally know where to look for the child you want */
我还尝试创建一个新的OnItemClickListener 并实现它的onItemClick 方法。尽管文档表明onItemClickListener 可以在ExpandableListViews 上以某种方式工作,但我从未见过它被调用过。
我尝试更改所选子项的背景颜色并使其突出显示的第一件事效果不佳。我在selector XML 文件中为android:state_window_focused="true" 设置了一个Drawable。它有点工作,但出现了几个问题。
我尝试的第二件事是通过调用viewClicked.setSelected(true); 明确选择onChildClick 中按下的项目。这里的问题更少:
1)如果我滚动直到突出显示的项目不在视线范围内并返回,突出显示消失了,2)如果我旋转手机也会发生同样的情况,3)突出显示的项目的状态不再当它在显示屏上不再可见时立即被选中。
Android 的ExpandableListView 显然不应该像手风琴式的左侧导航菜单那样工作,尽管这似乎是一个相当明显的用途。如果您想以这种方式使用它,我认为您必须进行大量自定义并深入研究Views 的绘制方式。
祝你好运。