繁体   English   中英

NavigationView 中带有菜单的自定义布局?

[英]Custom layout with menu in NavigationView?

我需要创建一个导航抽屉,这样,第一个菜单包含 5 个预定义项目(这些永远不会改变)。 在第一个菜单下方,我想要第二个菜单,其中包含具有自定义布局的可变数量的项目。

用一张图解释:

在此处输入图像描述

这是我现在的主要活动的样子:

<android.support.v4.widget.DrawerLayout
    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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="match_parent"
                android:layout_height="48dp" />

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

        <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

    <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">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <include
                layout="@layout/nav_header_drawer" />

            <ListView
                android:id="@+id/drawer_listview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="left"
                android:choiceMode="singleChoice" />

        </LinearLayout>

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

</android.support.v4.widget.DrawerLayout>

哪个有效,除了现在我不能为NavigationView使用app:menu="@menu/navigation_drawer_items"属性,因为ListView项与菜单项重叠。

这是菜单 XML:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Communicate">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_menu_share"
                android:title="Share" />
            <item
                android:id="@+id/nav_send"
                android:icon="@drawable/ic_menu_send"
                android:title="Send" />
        </menu>
    </item>
</menu>

有没有办法可以加载菜单 XML在菜单下方显示自定义布局? 有不同的想法吗?

NavigationView 似乎不支持自定义页脚。 在我的项目中,我根据其他一些 SO 答案制作了这个小怪物。

<android.support.v4.widget.DrawerLayout
     android:id="@+id/drawer_layout"
     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:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/colorPrimary"
     android:fitsSystemWindows="true"
     tools:context=".ui.MainActivity">

    ...screen content...

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="bottom"
            android:orientation="vertical">

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1">

                <android.support.design.widget.NavigationView
                    android:id="@+id/navigation_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top"
                    app:elevation="0dp"
                    app:headerLayout="@layout/drawer_header"
                    app:menu="@menu/drawer">
                </android.support.design.widget.NavigationView>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="21dp"
                    android:layout_alignParentBottom="true"
                    android:background="@drawable/bg_navbarscroll"/>

            </RelativeLayout>

            <include
                android:id="@+id/premium_footer"
                layout="@layout/drawer_footer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

我们这里有两个嵌套的 NavigationView。 这可能有点矫枉过正,但我​​无法让它工作。 这是基于这个问题中的工作,所以所有的功劳都在那里: 如何向 NavigationView 添加页脚 - Android 支持设计库?

真正的 NavView 是内部的,它有标题,有菜单,但它不适合系统窗口。 第一个适合系统窗口并处理抽屉移动。 您面临的问题是因为 ListView 不知道 NavView 中内容的大小。 所以你需要确保没有任何东西在同一个布局中,所以没有重叠。 您的 listView 必须在 NavView 父级的父级中。 而且因为这可能会破坏 DrawerLayout 控件的机制,所以您需要第一个外部 NavigationView。

或者,如果您可以在不膨胀抽屉中的菜单的情况下生活,只需制作一个自定义的“老式”抽屉,就像 NavigationViews 出现之前的抽屉一样。

就我而言,我想在抽屉底部添加一些信息文本。 在摆弄了一下之后,我设法通过在NavigationView中添加ConstraintLayout来获得所需的结果:

    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <include
            android:id="@+id/app_bar"
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />


        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <TextView
                    android:id="@+id/bottom_content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </com.google.android.material.navigation.NavigationView>

目前看来一切正常,但可能存在一些隐藏的陷阱。

导航菜单中的固定(非滚动)页脚可以通过将 NavigationView 包裹在另一个布局周围来实现,就像您发布的那样。 您可以安排它,使用 LinearLayout 作为页脚项目,如下所示:

<android.support.design.widget.NavigationView
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/drawer">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:clickable="true"
    android:orientation="vertical">
    <TextView
        android:id="@+id/footer_item_1"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center"
        android:text="Footer Item 1" />
    <TextView
        android:id="@+id/footer_item_2"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center"
        android:text="Footer Item 2" />
</LinearLayout>

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

你可以使用任何你想要的东西来代替 TextViews。 有必要很好地构建底部布局以避免视图重叠。

菜单 XML

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Communicate">
    <menu>
        <item
            android:id="@+id/nav_share"
            android:icon="@drawable/ic_menu_share"
            android:title="Share" />
        <item
            android:id="@+id/nav_send"
            android:icon="@drawable/ic_menu_send"
            android:title="Send" />
    </menu>
</item>

您终于可以将 onclick 侦听器添加到您的布局中

View navFooter1 = findViewById(R.id.footer_item_1);
navFooter1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do footer action
    }
});
View navFooter2 = findViewById(R.id.footer_item_2);
navFooter2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do footer action
    }
});

这将帮助您必须在 recyclerView 中设置自定义适配器。

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".DrawerActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/purple_200" />

    </LinearLayout>


    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">


            <include layout="@layout/header_layout" />


            <androidx.recyclerview.widget.RecyclerView

                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </LinearLayout>

    </com.google.android.material.navigation.NavigationView>

</androidx.drawerlayout.widget.DrawerLayout>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM