前言
又到了周五,提前祝大家周末愉快。虽然心情很激动,但是文章还是要写的,今天给大家带来Material design系列的第六篇文章,NavigationView的使用。
正如其名,NavigationView,导航View。一般我们用它和DrawerLayout实现抽屉式导航设计,很多App也用到了这个控件,国内的比如知乎,国外的例如Google自己的那些app,也基本全都采用了NavigationView。
那么这里我先给大家看一下效果,然后我们再来慢慢说如何实现这样的效果。
使用
首先还是要依赖design,这个我就不贴代码了,前面文章已经说过
在xml中添加DrawerLayout和NavigationView
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<!--这里是内容视图-->
<include layout="@layout/content_view_main"/>
<!--这里是侧拉视图-->
<android.support.design.widget.NavigationView
android:id="@+id/nav"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
内容视图的xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/app_name"
android:textSize="30sp"/>
</LinearLayout>
做到这一步,我们运行看一下效果(PS:这里由于我个人比较喜欢黑色,所以把colorPrimary和colorPrimaryDark都改成了黑色)
大家可以看到,我已经可以从左边把NavigationView拉出来了,但是里面是空白的,那么接下来我们就往里面添加数据。
添加headerLayout和menu
我们在xml下的NavigationView中添加两行属性,app:headerLayout和app:menu,就像这样头部布局的代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@drawable/head"
android:orientation="vertical"
android:padding="20dp">
<ImageView
android:id="@+id/iv_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:src="@mipmap/ic_launcher_round"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="LiXiaoTong"
android:textColor="#FFF"
android:textSize="20sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="这是一个NavigationView"
android:textColor="#FFF"/>
</LinearLayout>
menu文件的代码
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--只允许一个条目被选中 -->
<group
android:checkableBehavior="single">
<item
android:id="@+id/chat"
android:icon="@drawable/chat"
android:title="chat"/>
<item
android:id="@+id/contact"
android:icon="@drawable/contact"
android:title="contact"/>
<item
android:id="@+id/debt"
android:icon="@drawable/contact_debt"
android:title="debt"/>
<item
android:id="@+id/remark"
android:icon="@drawable/contact_remark"
android:title="remark"/>
</group>
<item android:title="Other">
<menu>
<item
android:id="@+id/phone"
android:icon="@drawable/phone"
android:title="phone">
</item>
<item
android:id="@+id/refresh"
android:icon="@drawable/refresh_list"
android:title="refresh">
</item>
</menu>
</item>
</menu>
设置完之后我们再看看效果
效果很明显,但是有一个小问题,我们左边的图片全部都是一个颜色了,那么我们来解决这个问题。
解决图标颜色统一
在代码中调用navigationView.setItemIconTintList(null);
就可以解决这个问题。
添加图标告诉用户打开NavigationView
如果我们不加点提示的话,用户可能根本不知道我们有侧拉菜单这个东西,所以这里我们加一个小图标以提示用户。
1. 用toolbar代替actionbar
在头部布局中添加
<!-- android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
这两行代码的作用是把ToolBar的文字和图标变成白色,不需要可以不加-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:background="@color/colorPrimary"
android:layout_height="?attr/actionBarSize"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
把app的主题改为Theme.AppCompat.Light.NoActionBar
在代码中用toolbar代替actionbar
2. 找到DrawerLayout并添加滑动监听
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, mDrawerLayout, toolbar, R.string.open, R.string.close);
mDrawerLayout.addDrawerListener(toggle);
//实现toolbar和Drawer的联动
toggle.syncState();
做到了这里我们再看一下效果
可以看到左边有一个三条杠的图标,并且NavigationView覆盖面积更大了,但是这里NavigationView上面有一个黑色区域,体验不太好,所以我们做一下沉浸式处理。
沉浸式处理
这里用到了github上面一个不错的开源项目,添加依赖
compile 'com.jaeger.statusbarutil:library:1.4.0'
依赖之后,在DrawerLayout和NavigationView中添加
android:fitsSystemWindows="true"
属性。
在代码中调用StatusBarUtil.setColorForDrawerLayout(this, mDrawerLayout, ContextCompat.getColor(this, R.color.colorPrimary));
即可实现沉浸式。
给条目设置点击事件
在代码中调用setNavigationItemSelectedListener
方法
然后重写onNavigationItemSelected
方法
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.chat:
mTv.setText("chat");
Snackbar.make(mTv, "chat", Snackbar.LENGTH_SHORT).show();
break;
}
//关闭侧拉菜单
mDrawerLayout.closeDrawer(GravityCompat.START);
return true;
}
获取头部的控件
调用navigationView.getHeaderView(0);
即可拿到头部布局
重写返回键关闭NavigationView
@Override
public void onBackPressed() {
//重写返回键,如果侧拉菜单已打开则关闭侧拉菜单
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
总结
大功告成,到这里我们的NavigationView就全部结束了,如果大家在使用过程中碰到什么问题或者我文章中有什么没有提到的欢迎大家留言,我会及时补充和解答,文章最后再次祝大家周(天)末(天)愉(吃)快(鸡)~