在NavigationView中使用菜单自定义布局?

时间:2017-02-06 22:14:23

标签: android android-layout android-navigation-drawer

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

在图片中解释:

enter image description here

以下是我现在的主要活动:

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

哪个有效,但现在我不能使用app:menu="@menu/navigation_drawer_items" NavigationView属性,因为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 AND 在菜单下面显示自定义布局?是否有不同的想要这样做?

3 个答案:

答案 0 :(得分:0)

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。这可能有点矫枉过正,但我​​无法使其工作。这是基于这个问题的工作,所以所有的功劳都在那里:How to add footer to NavigationView - Android support design library?

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

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

答案 1 :(得分:0)

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

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

目前看来一切正常,但是可能存在一些隐患。

答案 2 :(得分:0)

导航菜单中的固定(非滚动)页脚可以通过将 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>

你可以使用任何你想要的东西来代替 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
    }
});