代码之家  ›  专栏  ›  技术社区  ›  glenatron

如何在android上将可扩展列表视图与常规菜单项一起放入菜单?

  •  0
  • glenatron  · 技术社区  · 7 年前

    我正在使用 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 包含菜单的,它在其他菜单项上打开,似乎没有移动它们的方法。

    为了解决这个问题我把 多级列表 为菜单提供标题的单独布局。现在一切都画对了 但是 我不能再打开列表视图了,这肯定是个问题。事实上它是开放的-或者至少 onGroupExpandListener 已触发-但标题的高度设置为 wrap_content 而我 invalidate 它在展开和折叠时,头部的大小始终保持不变。为了解决这个问题,我正在手动更改 OnGroupExpandListener onGroupCollapseListener 如下所述。

    在我的布局中,我有一个这样的导航视图:

     <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() 为您提供您可能期望的维度),但实际的子项永远不会被呈现。在一个 onGroupClickListener 没有什么不同,尽管我怀疑子元素是从视图中剔除的,因为布局系统假定它们是不可见的,而不是正在调整大小的视图。如果我手动使标题更高,以便展开可展开列表时所有内容都在视图中,则它会正常打开和关闭,但显然这不允许我上下移动其他菜单项,这就是全部要点。

    对于必须是通用用例的情况来说,这一切似乎过于复杂 所以如果我在这里采取了完全错误的方法,请让我知道。我只希望菜单中的第一个项目是可展开列表,其他菜单项是常规菜单项,当可展开列表打开时向下移动,关闭时向上移动。

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

    编辑:随着时间的推移,我认为列表正在绕过绘制新的部分,因为它已经测量到它们没有可见的空间-尽管可以从 OnGroupClickListener 可见大小的实际更改在下一个图形通过之前不会发生,因此当基ListView测试是否有空间写入列表时,它将变为false。

    1 回复  |  直到 7 年前
        1
  •  0
  •   glenatron    7 年前

    我没有找到一种使用传统菜单的方法来实现这一点-相反,我找到的解决方案是将其他菜单项添加为 ExpandableListView 组,以便它们只显示在列表视图的顶层。这让我创造了我想要的效果,代价是不使用“正确”的菜单。