ExpandableListView打开折叠问题

问题描述 投票:0回答:5

我正在使用自定义可扩展列表适配器。当用户单击某个子项时,我会突出显示该子项。在用户打开/折叠组之前,这一切正常。假设用户触摸组 2 项目 1。这将突出显示组 2 项目 1。然后用户打开组 1。现在突出显示组 3 项目 2。我已经做了一些选择不同项目的测试,但找不到突出显示的行将跳转到的模式。有时它在列表中向上,有时它在列表中向下。我无法弄清楚放入活动的

onGroupExpandListener
onGroupCollapseListener
以重新突出显示正确视图的逻辑。有什么想法吗?

编辑:我的 onChildClickListener 中的当前代码

if (groupPosition == 0){ 
      switch(childPosition) {
      case 0: 
        previouslySelectedView.setBackgroundResource(R.color.transparent);
        currentlySelectedView.setBackgroundResource(R.color.blue); 
        break;

所有团体/儿童使用相同的代码

java android expandablelistview
5个回答
2
投票
ExpandableListView 中的项目选择是通过平面列表(绝对定位)进行的。因此,如果新打开的组位于当前选择之前并且具有较少的子组,则选择将向上移动,反之亦然。我建议将选择模式设置为 none 并实现 onclick/expand 逻辑来处理您自己的焦点 - 例如,为视图实现标签,并通过标签设置当前突出显示的项目。

以下是一些建议:

    在 ExpandableListView.OnChildClickListener 中,首先执行 ExpandableListView.findViewWithTag(theTag) 来检查具有此类标记的视图并取消标记它们(也可以 setTag(null))并恢复背景。然后对于该项目单击 setTag(theTag) 并将背景更改为选定的。当然,您可以有一些其他逻辑并标记多个项目。请注意,一旦视图被破坏,您将失去选择(例如在展开期间)。
  1. 拥有一些自定义地图或能够保存视图的唯一 ID 和(未)标记状态的东西。这是最好的解决方案,可以在滚动和展开之间保持持久的选择。
  2. 在支持适配器中引入“标记”状态。因此,即使在应用程序启动/停止之间,标记也将保持不变。但这不是一个好方法,因为选择更多的是一种 UI 行为。
我目前正在使用列表的选择模式倍数进行 ExpandableListView 选择。但正如我所说,由于选择是按位置进行的,因此我必须在功能方面做出牺牲 - 即,每当进行操作时我都会清除选择。之前的实现是使用自定义 Map 来保存选定的 ID,老实说,这是更好的方法。

这就是我获取选定 ID 的方法(记住我使用多重选择模式):

final SparseBooleanArray checkedPositions = expList.getCheckedItemPositions(); final ExpandableListAdapter adapter = expList.getExpandableListAdapter(); List<Long> checkedIds = new ArrayList<Long>(); if (packedPositionType == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { for (int i = checkedPositions.size() - 1; i >= 0; i--) { if (checkedPositions.valueAt(i)) { checkedIds.add(adapter.getGroupId(checkedPositions.keyAt(i))); } } }

不过,就您而言,您需要检查是否有儿童挤满的位置。另请注意,我的适配器具有稳定(唯一)的 ID。如果您没有稳定的 ID,那么您可以依靠 ExpandableListView 的 getPackedPositionForChild() 方法并将打包位置存储为标记。


2
投票
正确的做法(将解决组崩溃时突出显示的跳跃问题)

在 ExpandableListView 上执行以下操作:

步骤 1. 将选择模式设置为单一(可以在 xml 中完成,如 android:choiceMode = "singleChoice"

步骤 2. 使用选择器 xml 作为背景 (android:listSelector = "@drawable/selector_list_item")

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime"> <item android:drawable="@android:color/holo_blue_bright" android:state_pressed="true"/> <item android:drawable="@android:color/holo_blue_light" android:state_selected="true"/> <item android:drawable="@android:color/holo_blue_dark" android:state_activated="true"/> </selector>

第3步。在onChildClick()回调中调用expandableListView.setItemChecked(index,true)

index 是子项的从 0 开始的索引,计算如下

第 1 组 [索引 = 0]

    子项目 1
  • 子项目 2
  • 子项 3 [索引 = 3]

第 2 组 [索引 = 4]

    子项目 1
  • 子项目 2
  • 子项 3 [索引 = 7]

第 3 组 [索引 = 8]

    子项目 1
  • 子项目 2
  • 子项 3 [索引 = 11]
如果我们也有列表标题,它们也会考虑索引值。

这是一个工作示例:

@Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { ... int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition)); parent.setItemChecked(index, true); return true; }
    

0
投票
我对崩溃问题的解决方案:

mDrawerExpandableList.setOnGroupCollapseListener(new OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { if(ExpandableListView.getPackedPositionGroup(selectedFragmentId) == groupPosition) { mDrawerExpandableList.setItemChecked(mDrawerExpandableList.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(groupPosition)), true); } } }); mDrawerExpandableList.setOnGroupExpandListener(new OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { if(ExpandableListView.getPackedPositionGroup(selectedFragmentId) == groupPosition) { mDrawerExpandableList.setItemChecked(((ExpandableListView)drawerListView).getFlatListPosition(selectedFragmentId), true); } } });
    

0
投票
//MY LIST A FOLLOWS (0)SALES (0)SALES (1)SALES VIEW (2)SALES RETURN (3)SALES RETURN VIEW (1)STOCK (0)ADD STOCK (1)VIEW STOCK (2)SETTINGS (3)NOTIFICATION //declare tow integer variable globali as follows private int lastCheckedGroupPosition=-1; private int lastCheckedChildPosition=-1; mDrawerList.setOnGroupClickListener(new OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { if(groupPosition==2){ lastCheckedGroupPosition=groupPosition; lastCheckedChildPosition=-1; int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(groupPosition)); parent.setItemChecked(index, true); //TODO Write here the code for opening settings page ............... ............... ............... return true; } else if(groupPosition==3){ lastCheckedGroupPosition=groupPosition; lastCheckedChildPosition=-1; int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(groupPosition)); parent.setItemChecked(index, true); //TODO Write here the code for opening settings page ............... ............... ............... return true; } return false; } }); mDrawerList.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { if(groupPosition==0){ if(childPosition==0){ //TODO Write here the code for opening SALES page ............... ............... ............... } else if(childPosition==1){ //TODO Write here the code for opening SALES VIEW page ............... ............... ............... } else if(childPosition==2){ //TODO Write here the code for opening SALES RETURN page ............... ............... ............... } else if(childPosition==3){ //TODO Write here the code for opening SALES RETURN VIEW page ............... ............... ............... } } else if(groupPosition==1){ if(childPosition==0){ //TODO Write here the code for opening ADD STOCK page ............... ............... ............... } else if(childPosition==1){ //TODO Write here the code for opening VIEW STOCK page ............... ............... ............... } } int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition)); parent.setItemChecked(index, true); lastCheckedGroupPosition=groupPosition; lastCheckedChildPosition=childPosition; return false; } }); mDrawerList.setOnGroupExpandListener(new OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { if(groupPosition==lastCheckedGroupPosition){ if(lastCheckedChildPosition!=-1){ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForChild(lastCheckedGroupPosition, lastCheckedChildPosition)); mDrawerList.setItemChecked(index, true); } else{ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(lastCheckedGroupPosition)); mDrawerList.setItemChecked(index, true); } } else{ if(mDrawerList.isGroupExpanded(lastCheckedGroupPosition)){ if(lastCheckedChildPosition!=-1){ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForChild(lastCheckedGroupPosition, lastCheckedChildPosition)); mDrawerList.setItemChecked(index, true); } else{ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(lastCheckedGroupPosition)); mDrawerList.setItemChecked(index, true); } } else{ mDrawerList.setItemChecked(-1, true); } } } }); mDrawerList.setOnGroupCollapseListener(new OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { if(groupPosition==lastCheckedGroupPosition){ if(lastCheckedGroupPosition!=-1){ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(lastCheckedGroupPosition)); mDrawerList.setItemChecked(index, true); } else{ mDrawerList.setItemChecked(-1, true); } } if(mDrawerList.isGroupExpanded(lastCheckedGroupPosition)){ if(lastCheckedChildPosition!=-1){ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForChild(lastCheckedGroupPosition, lastCheckedChildPosition)); mDrawerList.setItemChecked(index, true); } else{ int index = mDrawerList.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(lastCheckedGroupPosition)); mDrawerList.setItemChecked(index, true); } } else{ mDrawerList.setItemChecked(-1, true); } } });
    

0
投票
我通过在

checkedGroupPosition

checkedChildPosition
中记录选中的组位置和子位置并更新
#onGroupExpand
#onGroupCollapse
中选中的项目来解决它:

override fun onGroupExpand(groupPosition: Int) { // Re-check the previous checked item because the flat position may have changed. updateCheckedItem() } override fun onGroupCollapse(groupPosition: Int) { // Re-check the previous checked item because the flat position may have changed. updateCheckedItem() } private fun updateCheckedItem() { // Checked item is a child item. if (checkedGroupPosition > -1 && checkedChildPosition > -1) { if (expandableListView.isGroupExpanded(checkedGroupPosition)) { // Check the item again if the group is expanded. expandableListView.setItemChecked( expandableListView.getFlatListPosition( ExpandableListView.getPackedPositionForChild(checkedGroupPosition, checkedChildPosition) ), true, ) } else { // Clear the checked item if its group is collapsed. expandableListView.setItemChecked(-1, true) } return } // Checked item is a group item, check the item again. if (checkedGroupPosition > -1) { expandableListView.setItemChecked( expandableListView.getFlatListPosition( ExpandableListView.getPackedPositionForGroup(checkedGroupPosition) ), true, ) } }
    
© www.soinside.com 2019 - 2024. All rights reserved.