Android 解决ListView视图中保留选定状态的奥秘

Android 解决ListView视图中保留选定状态的奥秘,android,listview,Android,Listview,不足为奇的是,有一天我看到了一款平板电脑优化设计,它在左侧显示了一个包含搜索结果的窗格,在右侧显示了相应的详细信息。左窗格上的结果具有选定状态,以指示当前显示的详细信息。看起来像是在公园里散步,结果却成了一次令人厌倦的反复试验之旅。但最后我设法让它工作起来,我删除了所有不相关的测试代码,却发现它已经立即停止工作了。我重新引入了“不相关”部分,令人惊讶的是它按计划工作 客户满意,设计师满意,但我不满意,因为我仍然不明白为什么它能像它那样工作 我有一个片段,它的ListView的choiceMode

不足为奇的是,有一天我看到了一款平板电脑优化设计,它在左侧显示了一个包含搜索结果的窗格,在右侧显示了相应的详细信息。左窗格上的结果具有选定状态,以指示当前显示的详细信息。看起来像是在公园里散步,结果却成了一次令人厌倦的反复试验之旅。但最后我设法让它工作起来,我删除了所有不相关的测试代码,却发现它已经立即停止工作了。我重新引入了“不相关”部分,令人惊讶的是它按计划工作

客户满意,设计师满意,但我不满意,因为我仍然不明白为什么它能像它那样工作

  • 我有一个片段,它的ListView的choiceMode设置为ListView。选择\u MODE\u SINGLE
  • 适配器为每个结果膨胀自定义视图,并设置一个可绘制的背景(发生在代码中)
  • drawable是一个封装在RippleDrawable中的选择器,它已使用drawable为需要保留的选定状态检查并激活状态
  • 自定义视图将覆盖setSelected(boolean selected),并依赖于boolean添加或删除具有选定状态的视图
  • 现在我的问题是3和4。检查并激活状态(步骤3)可确保在点击视图时调用setSelected(true),但在接地结束后,不会立即使用setSelected(false)再次调用setSelected(false),从而保持我在步骤4中设置的视图

    然而,我原以为在第4步中我不需要这个自定义视图,因为我认为它将在第3步中的激活状态中使用可绘制视图。从步骤4中删除自定义(因此与Android状态系统无关)视图的效果是,步骤3中可绘制的状态确实会显示,但仅在按下按钮(触地/保持)和。。。在上一个选定的项目上

    项目背景

    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
      android:color="@color/light_gray">
      <item android:drawable="@drawable/search_result_selector" />
    </ripple>
    
    selectedView是我在自定义视图类中定义的字段。我理解它为什么有效,但我想知道为什么我需要它,因为我希望状态可以正确使用并保留选择。奇怪的是,当我删除该部分时,
    ListView
    决定使用drawable,但只在上一个选定的视图上,并且仅在触地时使用。现在,为什么自定义实现的存在,而不是与任何Android API绑定,会影响Android视图状态的工作?很明显,它在某个地方被捆绑了,但我不知道在哪里。任何关于这一切背后原因的指示都会让我放心。提前谢谢你

    编辑
    显然我的一个结论是错误的。调用了setSelected(false),即使选择器中有状态也是如此。如果激活的是重要的状态,这可能是有意义的。我将代码移动到setActivated上的重写方法,它实际上显示了我的自定义视图。也就是说,奇怪之处仍然存在。。。状态drawable无法按预期工作。

    这是一个listview适配器视图回收问题,如中所述吗?不,似乎不是。问题也只存在于两个项目中。出现问题时,尚未回收任何视图。
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:drawable="@color/white_selected" android:state_selected="true"/>
      <item android:drawable="@color/white_selected" android:state_pressed="true"/>
      <item android:drawable="@drawable/search_result_highlighted_state" android:state_activated="true"/>
      <item android:drawable="@drawable/search_result_highlighted_state" android:state_checked="true"/>
      <item android:drawable="@color/white"/>
    </selector>
    
    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);
    
        if (selected && selectedView == null) {
            selectedView = new View(getContext());
            selectedView.setBackground(Utils.getDrawable(getContext(), R.drawable.action_bar_background));
    
            RelativeLayout.LayoutParams lp = new LayoutParams(Utils.pxFromDp(getContext(), 3), getHeight());
            lp.addRule(ALIGN_PARENT_RIGHT);
    
            addView(selectedView, lp);
        } else if (!selected && selectedView != null) {
            removeView(selectedView);
            selectedView = null;
        }
    }