NavigationView表示应用程序的标准导航菜单,菜单内容可以由菜单资源文件填充。NavigationView通常放在DrawerLayout中,可以实现侧滑效果的UI。DrawerLayout布局可以有3个子布局,第一个布局必须是主界面且不可以不写,其他2个子布局就是左、右两个侧滑布局,左右两个侧滑布局可以只写其中一个。下面就开始NavigationView的实练。
使用NavigationView控件需要导入design依赖包(我的运行环境是Android Studio 3.0,此版本中导入依赖包的关键字 不再是“compile”,而是改为了“implementation”,这里说明一下)
implementation 'com.android.support:design:28.0.0-alpha1'
先介绍下NavigationView控件的几个属性:
android:layout_gravity 值为start则是从左侧滑出,值为end则是从右侧滑出 app:menu NavigationView是通过菜单形式在布局中放置元素的,值为自己创建的菜单文件 app:headerLayout 给NavigationView设置头文件 app:itemTextColor 设置菜单文字的颜色 app:itemIconTint 设置菜单图标的颜色 app:itemBackground 设置菜单背景的颜色
下面一步步看下以上属性的效果。布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SNavigationViewActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是导航视图NavigationView"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>
运行效果如图:
因为刚刚没有给NavigationView创建菜单元素,所有左侧滑动和右侧滑动都是空白,现在增加菜单元素。在menu文件夹下新建菜单文件snavigation_view.xml文件:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group> <item android:id="@+id/item_argu" android:title="论坛" android:icon="@drawable/ic_menu_argu"/> </group> <group> <item android:id="@+id/item_book" android:title="头条" android:icon="@drawable/ic_menu_book"/> </group> <group> <item android:id="@+id/item_cloud" android:title="云空间" android:icon="@drawable/ic_menu_cloud"/> </group> <group> <item android:id="@+id/item_load" android:title="下载" android:icon="@drawable/ic_menu_load"/> </group> <group> <item android:id="@+id/item_rili" android:title="日历" android:icon="@drawable/ic_menu_rili"/> </group> <group> <item android:id="@+id/item_star" android:title="收藏" android:icon="@drawable/ic_menu_star"/> </group> </menu>
在左右两个NavigationView控件中增加菜单元素:
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end" app:menu="@menu/snavigation_view"> </android.support.design.widget.NavigationView>
运行效果如下:
下面给NavigationView增加头部布局,snavigation_view_header.xml如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp" android:orientation="vertical" android:gravity="center" android:background="@drawable/snavi_header_bg"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/avator"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="摸爬滚打的程序媛" android:padding="5dp" android:textColor="#FFFFFF"/> </LinearLayout>
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header"> </android.support.design.widget.NavigationView> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header"> </android.support.design.widget.NavigationView>
加完头部布局后运行再看一下效果:
为了节省篇幅,下面就只以左侧滑动为例进行其他属性的讲解。
设置菜单图标、文字的颜色:
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="#33a767" app:itemIconTint="#5fe935"> </android.support.design.widget.NavigationView>
运行效果如图:
如果设置菜单项被选中时的颜色变化,可以为图标、文字创建一个颜色选择器,未选中时是绿色,选中是红色。在color文件夹下新建选择器navigation_select.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#ff2200" android:state_checked="true"/> <item android:color="#33a767"/> </selector>
此时要注意的是,菜单文件snavigation_view.xml中的group标签要增加android:checkableBehavior="single"属性,否则看不到变化。
<android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="@color/navigation_select" app:itemIconTint="@color/navigation_select"> </android.support.design.widget.NavigationView>
运行效果如图:
以上实现的效果中是没有Toolbar的,下面实现一下DrawerLayout和Toolbar进行关联后的效果。
修改布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".NavigationViewActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:background="@color/colorPrimary"> </android.support.v7.widget.Toolbar> <android.support.v4.widget.DrawerLayout android:id="@+id/drawerlayout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是导航视图NavigationView"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/snavigation_view" app:headerLayout="@layout/snavigation_view_header" app:itemTextColor="@color/navigation_select" app:itemIconTint="@color/navigation_select"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> </LinearLayout>
代码:
public class NavigationViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private Toolbar toolbar; //要导入v7包下的 private DrawerLayout drawerLayout; private NavigationView navigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_navigation_view); toolbar=findViewById(R.id.toolbar); drawerLayout=findViewById(R.id.drawerlayout); navigationView=findViewById(R.id.navigation_view_left); //让DrawerLayout和Toolbar进行联动 顺序很重要! setSupportActionBar(toolbar); //让toolbar去取代actionbar getSupportActionBar().setDisplayHomeAsUpEnabled(true); //显示toolbar //下面的代码主要通过actionbardrawertoggle将toolbar与drawablelayout关联起来 ActionBarDrawerToggle actionBarDrawerToggle=new ActionBarDrawerToggle(this,drawerLayout,toolbar,0,0); drawerLayout.addDrawerListener(actionBarDrawerToggle); //设置监听 actionBarDrawerToggle.syncState(); //同步 //设置navigationView中菜单的点击事件 navigationView.setNavigationItemSelectedListener(this); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawers(); //点击菜单则收回drawerLayout return true; } }
运行效果如下:
让DrawerLayout和Toolbar进行联动之后,Toolbar左上角的图标是随着DrawerLayout滑出、收起而变化的。
关于NavigationView的补充:
1、实现菜单分割线,可以通过group实现,上面的菜单文件中,给每个group添加id属性后,运行就可以看到菜单之间的分割线了,效果如图:
2、想要动态修改菜单列表,可以通过以下代码实现。
MenuItem menuItem = navigationView.getMenu().findItem(R.id.menu_item);
menuItem.setVisible(false); // true 为显示,false 为隐藏
3、每个菜单项只有图标、文字,不能添加其他控件。无法设置每个菜单项的间隔距离。如果想要实现丰富布局的导航菜单,可以尝试将NavigationView控件替换成其他控件,如ListView,头布局可以通过listview的addHeaderView(),每个item可以根据需求定义自己的菜单布局。