首页 > 解决方案 > 如何将 ExpandableListView 与 Android 上的常规菜单项一起放入菜单中?

问题描述

DrawerLayout在我的 Android 应用程序上使用了一个运行良好的应用程序,但我遇到了菜单本身的问题,我希望在菜单中有一个可折叠的部分和一些静态项目。

我想要实现的确切布局是这样的:

Drawer Title

-> Expandable List
Menu Item 1
Menu Item 2

当可扩展列表打开时有这样的东西:

Drawer Title

-> Expandable List
   Expandable List Item 1
   Expandable List Item 2
Menu Item 1
Menu Item 2

我遇到的问题是菜单似乎不像其他元素那样位于视图流中,所以如果我的ExpandableListView内部NavigationView包含菜单,它会在其他菜单项上打开并且似乎没有成为移动它们的一种方式。

为了尝试解决这个问题,我将其移到了ExpandableListView一个单独的布局中,该布局为菜单提供了标题。这现在可以正确绘制所有内容,我无法再打开列表视图,这绝对是个问题。事实上它确实打开了——或者至少是onGroupExpandListener被触发了——但是虽然标题的高度设置为wrap_content并且我invalidate在展开和折叠时,标题的大小保持不变。为了解决这个问题,我手动更改它的大小,onGroupExpandListener如下onGroupCollapseListener所示。

在我的布局中,我有一个这样的 NavigationView:

 <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/drawer_view" >

 </android.support.design.widget.NavigationView>

标题如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
        <RelativeLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:background="@color/colorPrimary" >
                <ImageView
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:padding="10dp"
                    app:srcCompat="@drawable/main_icon" />

                <TextView
                    android:id="@+id/drawer_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentStart="true"
                    android:layout_centerVertical="true"
                    android:layout_gravity="left|start|center"
                    android:layout_marginStart="70dp"
                    android:paddingStart="5pt"
                    android:text="Options"
                    android:textColor="#FFFFFF"
                    android:textSize="16pt"
                    android:textStyle="bold" />
        </RelativeLayout>
        <ExpandableListView
            android:id="@+id/menu_expandable_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom" >
        </ExpandableListView>
</LinearLayout>

在我的代码中,我目前正在设置 ExpandableListView (完成了一堆多余的黑客,因为我试图找出问题),如下所示:

private void setOptionsMenuItems(final NavigationView menuContainer) {
    final View v = menuContainer.inflateHeaderView(R.layout.drawer_header);
    final ExpandableListView optionsMenu = (ExpandableListView) v.findViewById(R.id.menu_expandable_list);
    final MyExpandableListAdapter adapter = new MyExpandableListAdapter(this, allTheItems );
    optionsMenu.setAdapter(adapter);
    optionsMenu.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
            setCurrentItem(allTheItems[childPosition]);
            return true;
        }
    });

    optionsMenu.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
        @Override
        public void onGroupExpand(int groupPosition) {
            v.setMinimumHeight(v.getChildAt(0).getHeight() + adapter.getOpenHeight());
            v.invalidate();
        }
    });
    optionsMenu.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
        @Override
        public void onGroupCollapse(int groupPosition) {
            v.setMinimumHeight(v.getChildAt(0).getHeight() +  adapter.getClosedHeight());
            v.invalidate();
        }
    });
}

此版本的代码所做的是在组打开或关闭时正确放大和缩小标题(adapter.getOpenHeight()/getClosedHeight()为您提供您可能期望的尺寸),但实际的子项永远不会被渲染。在 anonGroupClickListener中进行相同的放大并没有什么不同,尽管我怀疑子元素正在从视图中剔除,因为布局系统假定它们是不可见的,而不是调整视图的大小。如果我手动使标题更高,以便在展开 ExpandableList 时所有内容都在视图中,它会正常打开和关闭,但显然这不允许我上下移动其他菜单项,这是重点。

对于一个常见的用例来说,这一切似乎都非常复杂,所以如果我在这里采取了完全错误的方法,请告诉我。我想要的只是我的菜单中的第一项是 ExpandableList,其他菜单项是常规菜单项,当 ExpandableList 打开时向下移动,关闭时向上移动。

我需要做什么才能在我的菜单中有一个可折叠的选项列表?

编辑:在这方面有更多时间,我认为正在发生的事情是该列表正在绕过绘制新部分,因为它已经测量到它们没有可见的空间 - 尽管可以从onGroupClickListener可见的实际变化中触发调整大小size 直到下一次绘制通过才会出现,因此当基础 ListView 测试是否有空间写入列表时,它会出现错误。

标签: javaandroidandroid-layout

解决方案


我没有找到使用传统菜单的方法来做到这一点——相反,我找到的解决方案是将我的其他菜单项添加为ExpandableListView组,以便它们简单地出现在列表视图的顶层。这使我能够以不以“正确”方式使用菜单为代价来创建我正在寻找的效果。


推荐阅读