ExpandableListView打开折叠问题

问题描述

| 我正在使用自定义可扩展列表适配器。当用户单击它时,我突出显示一个孩子。在用户打开/折叠组之前,此方法工作正常。假设用户触摸第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;
所有组/儿童使用相同的代码     

解决方法

ExpandableListView中的项目选择是通过平面列表(绝对位置)进行的。因此,如果新打开的组在选择curnet之前,并且子节点较少,则选择将向上移动,反之亦然。我建议将选择模式设置为无,并实现onclick / expand逻辑来处理您自己的焦点-例如,为视图实现标签,并通过该标签设置当前突出显示的项目。 以下是一些建议: 首先,在ExpandableListView.OnChildClickListener中,执行ExpandableListView.findViewWithTag(theTag)以检查带有此类标记的视图并将其取消标记(也为setTag(null))并恢复背景。然后为该项目单击setTag(theTag),并将背景更改为选定。当然,您可以具有其他逻辑并标记多个项目。请注意,一旦视图被破坏,您将丢失选择(例如,在展开期间)。 有一些自定义地图或将拥有视图的唯一ID和(未标记)状态的内容。这是最好的解决方案,它将允许在滚动和扩展之间保持持久选择。 在后备适配器中,引入“已标记”状态。因此,即使在应用程序启动/停止之间,标记也将保持不变。但是,这不是一个好方法,因为选择更多是一种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()方法并按标记存储打包位置。     ,正确的方法(解决组崩溃时跳出突出显示的问题) 在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;
}
    ,我对崩溃问题的解决方案:
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);
        }
    }
});
    ,
//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,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,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,true);                            
                }
            }
            else{
                mDrawerList.setItemChecked(-1,true);
            }

        }
    });