Java ExpandableListView打开崩溃问题

Java ExpandableListView打开崩溃问题,java,android,expandablelistview,Java,Android,Expandablelistview,我正在使用自定义的可扩展列表适配器。当用户单击一个子对象时,我会高亮显示它。在用户打开/折叠一个组之前,此操作可以正常工作。假设用户触摸第2组第1项。这突出了第2组第1项。然后用户打开组1。现在,第3组第2项突出显示。我已经做了一些选择不同项目的测试,但我找不到突出显示的行将跳转到的模式。有时它在列表中向上,有时它向下。我很难理解将逻辑放入活动的onGroupExpandListener和OnGroupCollapsElister中以重新高亮显示正确的视图。有什么想法吗 编辑:onChildCl

我正在使用自定义的可扩展列表适配器。当用户单击一个子对象时,我会高亮显示它。在用户打开/折叠一个组之前,此操作可以正常工作。假设用户触摸第2组第1项。这突出了第2组第1项。然后用户打开组1。现在,第3组第2项突出显示。我已经做了一些选择不同项目的测试,但我找不到突出显示的行将跳转到的模式。有时它在列表中向上,有时它向下。我很难理解将逻辑放入活动的
onGroupExpandListener
OnGroupCollapsElister
中以重新高亮显示正确的视图。有什么想法吗

编辑:onChildClickListener中的当前代码

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

ExpandableListView中的所有组/子项选择的代码相同,通过平面列表(绝对位置D)生成。因此,如果新打开的组在currenet选择之前,并且子项较少,则选择将向上移动,反之亦然。我建议将choice mode设置为none,并实现onclick/expand逻辑来处理您自己的焦点-例如,实现视图标记,并通过标记设置当前高亮显示的项

以下是一些建议:

  • 在ExpandableListView.OnChildClickListener中,首先执行ExpandableListView.findViewWithTag(tag),以检查是否有带有此类标记的视图,并取消标记它们(以及setTag(null))并恢复背景。然后为该项目单击setTag(标签),并将背景更改为selected。当然,您可以使用其他逻辑并标记多个项目。请注意,一旦视图被破坏,您将丢失选择(例如在展开过程中)
  • 有一些自定义地图或其他东西,可以保存视图的唯一ID和(未)标记状态。这是最好的解决方案,可以在滚动和展开时保持持久选择
  • 在支持适配器中,引入“标记”状态。因此,即使在应用程序启动/停止之间,标记也将保持不变。但这不是一个好方法,因为选择更多的是一种UI行为
  • 我目前正在使用列表的选择模式选择ExpandableListView。但是,正如我所说,选择是根据我不得不牺牲的功能性位置进行的——也就是说,每当进行操作时,我都会清除选择。以前的实现是使用保存选定ID的自定义映射,老实说,这是更好的方法

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

    final SparseBooleanArray checkedPositions=expList.getCheckedItemPositions();
    final ExpandableListAdapter=expList.getExpandableListAdapter();
    List checkedds=new ArrayList();
    if(packedPositionType==ExpandableListView.PACKED\u POSITION\u TYPE\u GROUP){
    对于(int i=checkedPositions.size()-1;i>=0;i--){
    if(检查位置。值(i)){
    add(adapter.getGroupId(checkedPositions.keyAt(i));
    }
    }
    }
    
    不过,在您的情况下,您需要检查是否有儿童拥挤的位置。还要注意,我的适配器具有稳定(唯一)的ID。如果您没有稳定的ID,那么您可以依赖ExpandableListView的getPackedPositionForChild()方法并按标记存储打包位置。

    正确的方法(将解决组崩溃时的跳转突出显示问题)

    在ExpandableListView上执行以下操作:

    步骤1。将选择模式设置为single(可以在xml中通过android:choiceMode=“singleChoice”完成)

    步骤2。使用选择器xml作为背景(android:listSelector=“@drawable/selector\u list\u item”


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

    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);
            }
        }
    });
    

    发布你的代码,这样我们就可以看到你是否做了一些可能导致这种情况的事情。我对标签做了一些研究。看起来这可能是一个解决方案,但如何通过编程方式为listview项提供标记?如何获取所单击视图的唯一id?它是视图的一部分吗?而且,一旦我存储了该id,我就不知道如何引用该视图。sudo代码类似于
    View v=findViewWithUniqueID(uniqueID)
    ?唯一ID可以由适配器设置为标记,或者您可以使用前面提到的压缩位置,这些位置基本上是列表视图位置的可扩展列表视图变体,但是,当包含所选项目的组折叠时,所选内容将丢失。
    <?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>
    
    @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, 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);
                }
    
            }
        });