【问题标题】:Stop ExpandableListView groups expanding while Contextual Action Bar is visible在上下文操作栏可见时停止 ExpandableListView 组扩展
【发布时间】:2014-01-23 14:00:27
【问题描述】:

我有一个包含ExpandableListView 的片段。我希望能够按 group 选择和删除项目。我还希望能够通过上下文操作栏选择多个组项进行删除。

到目前为止,我可以点击组查看孩子,也可以点击孩子去另一个活动。我将ExpandableListView 的选择模式设置为CHOICE_MODE_MULTIPLE_MODAL,如果我长按一个组,它被选中,就会出现一个上下文操作栏。如果我选择我的删除按钮,该项目将被删除。都好。

但是,当我尝试在 CAB 模式中选择 多个 组时,就会出现问题。它只是行不通。如果我单击第二个组,则会展开该组(未选中)。我希望能够仅突出显示多个组项而不会发生任何扩展。

有很多代码可以让这个工作,但我会尝试展示一些相关的部分。主要问题是获取选定组项目的列表。其次,我不希望在选择组时扩展组(虽然 CAB 是可见的 - 这是我通过在 mActionMode 中保持 ActionMode 所尝试的)。

非常感谢任何帮助。

ex.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        @Override
        public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) {
            // Ignore long clicks on children
            long pos = ex.getExpandableListPosition(position);
            if (checked && (ExpandableListView.getPackedPositionType(pos) == ExpandableListView.PACKED_POSITION_TYPE_CHILD)) {
                ex.setItemChecked(position, false);
                return;
            }
        }

        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            MenuInflater inflater = actionMode.getMenuInflater();
            inflater.inflate(R.menu.context_delete_items, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            mActionMode = actionMode;
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem item) {
            // If delete is clicked, delete the measurement set
            switch(item.getItemId()) {
                case(R.id.context_menu_delete_item):
                    Set<mySet> setsToDelete = new HashSet<mySet>();

                    if (ex != null) {
                        if (ex.getCheckedItemCount() > 0) {
                            SparseBooleanArray checkedPositions = ex.getCheckedItemPositions();
                            for (int i = 0; i < checkedPositions.size(); i++) {
                                int position = checkedPositions.keyAt(i);

                                /* Ignore selected children */
                                long pos = ex.getExpandableListPosition(position);
                                int groupPosition = ExpandableListView.getPackedPositionGroup(pos);


                                if (checkedPositions.valueAt(i)) {
                                    Log.d(TAG, "Adding MeasurementSet at position Key = " + position + " to deletion list");
                                    setsToDelete.add(mSets.get(groupPosition));
                                }

                            }
                        }
                    }

                    try {
                        if (ex != null && setsToDelete.size() > 0) {

                            ArrayList setsToDeleteList = new ArrayList(setsToDelete);
                            deleteSets(setsToDeleteList);

                            for (mySet s : setsToDelete) {
                                mSets.remove(s);
                            }

                            Toast.makeText(getActivity(), "Set deleted successfully", Toast.LENGTH_LONG).show();


                        }
                    } catch (SQLiteException sqlex) {
                        Log.e(TAG, "Delete operation failed");
                        Log.e(TAG, "Error was: " + sqlex.getMessage());
                        Log.e(TAG, "Stack trace: " + sqlex.getStackTrace());
                        Toast.makeText(getActivity(), "There was an error whilst deleting Set(s): " + sqlex.getMessage(), Toast.LENGTH_LONG).show();
                    }

                    actionMode.finish();
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public void onDestroyActionMode(ActionMode actionMode) {
            mActionMode = null;
        }
    });

    ex.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
            Long mId = mSets.get(groupPosition).getMyList().get(childPosition).getId();
            Intent intent = new Intent(getActivity(), ViewSingleActivity.class);
            intent.putExtra(getResources().getString(R.string.EXTRA_MID_KEY), measurementId);
            startActivityForResult(intent, Constants.REQ_VIEW_M);
            return true;
        }
    });

// Here I was trying to intercept group clicks and force the clicked group to collapse. Although this doesn't seem to solve the issue of having the group "selected"
    ex.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            if (mActionMode != null) {
                Log.d(TAG, "mActionMode is not null. Setting View: " + parent.toString() + " to be selected");
                v.setSelected(true);
                Log.d(TAG, "Collapsing group " + groupPosition);
                parent.collapseGroup(groupPosition);
            }
            return false;
        }
    });
}

【问题讨论】:

  • 我似乎在onGroupClick() 中使用parent.setItemChecked(groupPosition, true) 会导致我的组项目被选中,并允许我删除多个组。可悲的是,我仍然不能 1) 设置组的样式以将其显示为选中状态(更改背景颜色等) 2) 在单击组时停止扩展组(仅当 CAB 可见时)。
  • 巧合的是,我目前正在处理将 ExpandableListView 与上下文操作栏相结合的相同任务。为了将组显示为选中状态,您的组布局必须使用 android:background="?android:attr/activatedBackgroundIndicator"
  • 最初我的组项目根视图是&lt;CheckedTextView&gt;,这种方法不起作用。我将其更改为包含&lt;TextView&gt;&lt;LinearLayout&gt;,现在我的组项目显示为选中!谢谢!但是,有没有办法改变高光颜色?再次感谢。
  • 对于其他对此感到疑惑的人,答案很好here
  • 只是稍微捎带一下:如果有人知道如何获得组项目位置(用于选中/取消选中)无论组是否扩展,我都会非常感激.我无法理解所有这些拥挤的位置、平坦的位置等。

标签: android expandablelistview android-4.4-kitkat expandablelistadapter


【解决方案1】:

虽然这是一篇旧帖子,但我想如果有人偶然发现我会发布答案。问题是ExpandableListView 不支持ChoiceMode。虽然它似乎可以正常工作,但您可以手动调用ExpandableListView 来设置检查项目......它永远不会完全正常工作。对于原因的更深入的原因;请参阅thisthis SO 答案。

OP 没有说明他们是否编写了自己的自定义适配器。所以我将解决这两种方法。

如果您想编写自己的自定义ExpandableListAdapter,我建议使用PatchedExpandabeListAdapter。你可以阅读它here。基本上它修补和改进了一些东西......其中之一是 OP 提出的 ChoiceMode 问题。

如果您不想推出自己的解决方案,可以找到两个不错的成熟 Rolodex 适配器 here,它实现了 PatchedExpandabeListAdapter 以及除了视图生成之外您需要的大部分内容。

【讨论】:

    猜你喜欢
    • 2013-07-12
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多