NavigationView导航视图与DrawerLayout绘制布局

目录

1. 基础使用方法:

(1) 准备NavigationView的hearderLayout和menu的XML文件

(2) 创建DrawerLayout,并在DrawerLayout放置NavigationView

(3) 设置NavigationView菜单项监听及其他设置

2. 显示自定义菜单项的菜单:

(1) 创建自定义菜单项的xml布局文件

(2) 设置菜单项布局为自定义菜单项

(3)设置自定义菜单项中的子控件及Header中的子控件

3. 展开/关闭 DrawerLayout中的NavigationView

(1) Java代码展开

(2) 手势操作展开

(3) Java代码关闭

(4) 手势操作关闭 

4. 常见的问题

(1) 监听器无法触发

(2) Menu自定义布局不显示

(3) Menu自定义布局重叠


NaviagtionView(导航视图)需与DrawerLayout(绘制布局)配合使用。

DrawerLayout中的Navigation有两种表现方式,左划出和右划出,可在<NaviagtionView>标签中使用android:layout_gravity属性设置,值为start时为左划出,为end时为右划出。一个DrawerLayout中可以同时含有左划出和右划出的两个导航视图,和Activity主体空间

NaviagtionView中有两部分,上部分的header和下部分的menu,可在<NaviagtionView>标签中使用android:headerLayout和android:menu属性设置。但这两个部分也可以有不设置的,或都不设置。其中菜单可以为自定义菜单项的菜单。

1. 基础使用方法:

(1) 准备NavigationView的hearderLayout和menu的XML文件

NavigationView默认展示菜单的title和icon的黑色阴影图标,但NavigationView支持显示自定义菜单项布局的菜单,详情请见下文。

<menu>中tools:showIn="navigation_view"可让预览图为菜单在导航视图中的样子。

//  res\layout\navigation_view_header_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!-- 该部分为NaviagtionView上部分,高度不能为match_parent,要为menu留空间 !-->

</RelativeLayout>
//  res\menu\navigation_view_menu.xml

<!--  该菜单用于NavigationView下部分 !-->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:showIn="navigation_view">
    <item
        android:id="@+id/item1"
        android:title="title1"
        android:icon="@drawable/icon1" />
    <item
        android:id="@+id/item2"
        android:title="title2"
        android:icon="@drawable/icon2" />
</menu>

(2) 创建DrawerLayout,并在DrawerLayout放置NavigationView

请确保NavigationView位于DrawerLayout中所有控件的最后,确保它是 DrawerLayout 的最后一个子 View。这样可以确保 NavigationView 处于较高的 Z 轴顺序,使其能够响应触摸事件。

在DrawerLayout中使用tools:openDrawer属性可以使预览图中的NavigationView展开,方便编写。

在DrawerLayout中放入NavigationView后一定要设置android:layout_gravity为start或end,用于设置左划出或右划出。

NaviagtionView中有两部分,上部分的header和下部分的menu,可在可在<NaviagtionView>标签中使用android:headerLayout和android:menu属性设置。但这两个部分也可以有不设置的,或都不设置。

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"

    tools:openDrawer="start"
                             >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- Activity主体空间 !-->
    </RelativeLayout>

    <com.google.android.material.navigation.NavigationView
        android:layout_width="250dp"
        android:layout_height="match_parent"
        android:id="@+id/navigationView"

        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_view_header_layout"
        app:menu="@menu/navigation_view_menu"
                                              />

</androidx.drawerlayout.widget.DrawerLayout>

(3) 设置NavigationView菜单项监听及其他设置

//  MainActivity.java
NavigationView navigationView=findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    public boolean onNavigationItemSelected(MenuItem item) {
        //选中菜单项执行
        int menuItemId=item.getItemId();
        return true;
    }
});
        
//如为自定义菜单项,可进行子控件设置
//例:
Menu menu=navigationView.getMenu();
View menuItemView=menu.findItem(R.id.item1).getActionView();
ImageView imageView=menuItemView.findViewById(R.id.~);
imageView.setImageResource(R.drawable.~);

//设置NavigationView中header的子控件
//当只有一个header时,getHeaderView的参数index为0
View headerView=navigationView.getHeaderView(0);
TextView headerTextView=headerView.findViewById(R.id.navigation_view_head_textView);
headerTextView.setText("Str");

//DrawerLayout绘制布局显示NavigationView导航视图
DrawerLayout drawerLayout=findViewById(R.id.drawerLayout);
drawerLayout.openDrawer( GravityCompat.START );
drawerLayout.openDrawer( GravityCompat.END );

2. 显示自定义菜单项的菜单:

NavigationView支持显示自定义菜单项布局的菜单,用于替代只能显示黑色icon阴影图标与title的菜单。

在菜单项中添加app:actionLayout属性即可自定义菜单项布局。在设置本属性时请不要设置title,可能会导致冲突,可用tools:ignore="MenuTitle"替代title。

请注意是app:actionLayout不是android:actionLayout

(1) 创建自定义菜单项的xml布局文件

//  res\layout\menu_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    
    <!--  自定义菜单项 !-->

</RelativeLayout>

(2) 设置菜单项布局为自定义菜单项

在菜单项中添加app:actionLayout属性即可自定义菜单项布局

<menu>中tools:showIn="navigation_view"可让预览图为菜单在导航视图中的样子。

//  res\menu\navigation_view_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:showIn="navigation_view">
    <item
        android:id="@+id/item1"
        app:actionLayout="@layout/menu_item_layout"
        tools:ignore="MenuTitle" />
    <item
        android:id="@+id/item2"
        app:actionLayout="@layout/menu_item_layout"
        tools:ignore="MenuTitle"/>
</menu>

(3)设置自定义菜单项中的子控件及Header中的子控件

使用自定义菜单项时可使用navigationView.getMenu()获取菜单对象,使用menu.findItem()获取指定菜单项,然后使用getActionView()获取菜单项的View,最后使用view.findViewById()获取指定控件。

使用navigationView.getHeaderView(int index)获取Header的View对象,使用view.findViewById()获取指定控件。

//  MainActivity.java
//如为自定义菜单项,可进行子控件设置
//例:
Menu menu=navigationView.getMenu();
View menuItemView=menu.findItem(R.id.item1).getActionView();
ImageView imageView=menuItemView.findViewById(R.id.~);
imageView.setImageResource(R.drawable.~);

//设置NavigationView中header的子控件
//当只有一个header时,getHeaderView的参数index为0
View headerView=navigationView.getHeaderView(0);
TextView headerTextView=headerView.findViewById(R.id.navigation_view_head_textView);
headerTextView.setText("Str");

3. 展开/关闭 DrawerLayout中的NavigationView

(1) Java代码展开

//DrawerLayout绘制布局显示NavigationView导航视图
DrawerLayout drawerLayout=findViewById(R.id.drawerLayout);
drawerLayout.openDrawer( GravityCompat.START );
drawerLayout.openDrawer( GravityCompat.END );

(2) 手势操作展开

长按边缘然后向中间划动。

(3) Java代码关闭

//DrawerLayout绘制布局显示NavigationView导航视图
DrawerLayout drawerLayout=findViewById(R.id.drawerLayout);
drawerLayout.closeDrawer( GravityCompat.START );
drawerLayout.closeDrawer( GravityCompat.END );

(4) 手势操作关闭 

NavigationView向两边划动。

4. 常见的问题

(1) 监听器无法触发

NavigationItemSelectedListener失效可能是因为NavigationView在DrawerLayout中所处的位置无法接收到触碰事件。

请确保NavigationView位于DrawerLayout中所有控件的最后,确保它是 DrawerLayout 的最后一个子 View。这样可以确保 NavigationView 处于较高的 Z 轴顺序,使其能够响应触摸事件。

(2) Menu自定义布局不显示

NavigationView中的Menu如果使用自定义列表项布局,不显示的原因大概率是布局引用属性使用错误或未使用。

正确的使用方法是在<item中使用app:actionLayout="@layout/menu_item_layout"请注意是app不是android,系统可能会建议android,请更改为app。

(3) Menu自定义布局重叠

NavigationView中的Menu如果使用自定义列表项布局,布局重叠的原因大概率是item中使用了title属性,删除该属性或用tools:ignore="MenuTitle"替代即可解决。

tag: 导航栏 , 绘制布局  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下嗷呜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值