【问题标题】:onItemCheckedStateChanged() is called only once on custom ExpandableListViewonItemCheckedStateChanged() 仅在自定义 ExpandableListView 上调用一次
【发布时间】:2014-01-24 23:53:33
【问题描述】:

我正在尝试在我的自定义 ExpandableListView 中实现多项选择,这是 Java 代码和组布局:

Java

mExpandable.setChoiceMode(ExpandableListView.CHOICE_MODE_MULTIPLE_MODAL);
        mExpandable.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
            @Override
            public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) {
                if(DEBUG) Log.i("mFragmentList","onItemCheckedStateChanged()");

                if(mExpandable.getCheckedItemCount() == 0)
                    actionMode.setSubtitle("Check some items!");
                else if(mExpandable.getCheckedItemCount() == 1)
                    actionMode.setSubtitle("1 item selected");
                else
                    actionMode.setSubtitle(mExpandable.getCheckedItemCount() + " items selected");
            }

            @Override
            public boolean onCreateActionMode(ActionMode actionMode, android.view.Menu menu) {
                actionMode.setTitle("Select Items");
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode actionMode, android.view.Menu menu) {
                return true;
            }

            @Override
            public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
                return true;
            }

            @Override
            public void onDestroyActionMode(ActionMode actionMode) {

            }
        });

group_row.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/activated">

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:scaleType="center"
        android:layout_centerVertical="true"
        android:adjustViewBounds="true"
        android:layout_gravity="left"
        android:src="@drawable/ball" />

    <TextView
        android:id="@+id/tvGroupName"
        android:paddingLeft="35dp"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FFFF0000"
        android:textSize="17sp" />

</RelativeLayout>

当我长按某个项目时,该项目被选中并创建了 ActionMode,但是如果我想选择另一个项目,则该项目将被展开并且不再调用 onItemCheckedStateChanged(),因此我不能选择多个项目.我试图将CHOICE_MODE_MULTIPLE_MODAL 放入 XML 中,但我什至无法选择一项。我错过了什么?截图如下:

【问题讨论】:

  • Andres,首先,非常感谢源代码。我尝试使用您在此链接中发布的 MultiChoiceMode 导入源代码:Eclipse 中的github.com/dragondgold/AnimatedExpandableListView,但它不起作用。我知道您是在 Android Studio 中完成的。我怎样才能让它在 Eclipse 中工作?谢谢
  • 我认为你应该从源代码创建一个项目,或者你可以创建一个项目并复制。 java文件

标签: android expandablelistview


【解决方案1】:

好吧,我终于用解决方法解决了。

mExpandable.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                if(actionModeEnabled)
                    expandableListView.setItemChecked(i, !expandableListView.isItemChecked(i));

                return actionModeEnabled;
            }
        });

mExpandable.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
    @Override
    public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) {
        if(mExpandable.getCheckedItemCount() == 1)
            actionMode.setSubtitle("1 item selected");
        else
            actionMode.setSubtitle(mExpandable.getCheckedItemCount() + " items selected");
    }

    @Override
    public boolean onCreateActionMode(ActionMode actionMode, android.view.Menu menu) {
        actionModeEnabled = true;
        actionMode.setTitle("Select Items");
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, android.view.Menu menu) {
        return true;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode) {
        actionModeEnabled = false;
    }
});

因此,当我长按某个项目时,会启用动作模式并按预期检查第一个项目。为了继续选择项目,我设置了一个OnGroupClickListener,所以现在当我单击一个项目时,我使用setItemChecked() 选择/取消选择它,并在启用操作模式时返回true,因此列表不会被扩展,只是被选中.

【讨论】:

    【解决方案2】:

    你的回答对我来说几乎是正确的,但我有一个问题。

    问题出在这里:

    @Override
    public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) {
        if(mExpandable.getCheckedItemCount() == 1)
            actionMode.setSubtitle("1 item selected");
        else
            actionMode.setSubtitle(mExpandable.getCheckedItemCount() + " items selected");
    }
    

    当组折叠时,它工作正常。但例如,如果我有这样的结构:

    - Group 1
        + Child 1
    - Group 2
        + Child 2
    

    如果我在第 2 组中长按,我期望的 onItemCheckedStateChanged 中的位置是 1(因为我们从 0 开始,第 1 组 = 位置 0,第 2 组 = 位置 1)。但是该方法的位置= 2!所以它选择了一个不存在的行。我认为这种行为是因为当孩子们展开时,第 2 组的索引为 2(在示例中)。如何解决此问题以正确使用带有组行的 CAB?就好像它是一个普通的 ListView。

    【讨论】:

    • 是的,我也遇到了这个问题,我不知道如何解决,所以我决定使用github.com/tjerkw/Android-SlideExpandableListView,它还可以为展开/折叠动作设置动画。 MultiChoiceMode 无法正常工作,因此我将其移植到 Android Studio 并对其进行了修改以使用 MultiChoiceMode,请参阅此处的代码:github.com/dragondgold/AnimatedExpandableListView
    • 我试过了,效果很好!我只是我有一个问题。在适配器启动 listView.smoothScrollBy(..) 后,它使 listview 在必要时滚动,当我单击一个元素时,第一次单击将被忽略(并且您必须单击两次)。我正在尝试对 onInterceptTouchEvent 做一些事情,但在某些情况下它总是失败。你也有这种情况吗?
    • 我不确定我是否理解你。您说当库中使用listView.smoothScrollBy(..) 滚动列表以使单击的项目可见时,忽略下一个单击事件?我没有这个问题。
    • @DIFTOR 给我发电子邮件,附上显示正在发生的事情的屏幕截图或视频,也许我可以帮助你。
    猜你喜欢
    • 2012-04-28
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多