Android NavigationDrawer(侧滑导航栏 DrawerLayout + NavigationView)


本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/90487113


Google官方出品的侧滑导航栏, 可替换长期未维护的SlidingMenu.
除此之外, 还有个第三方开源库MaterialDrawer可供选择

Navigation DrawerMaterial Design 中的侧滑导航栏, 由抽屉布局 DrawerLayout 和 导航View NavigationView 组成.

快速创建

  • 新建项目时:
    • 新建项目时, 最后一页"Add an Activity to Mobile" 选择 Navigation Drawer Activity
  • 新建Activity时:
    • 在已有的项目, 创建Activity选择 Navigation Drawer Activity

手撸实现

抽屉布局 DrawerLayout

<?xml version="1.0" encoding="utf-8"?>        

其中 NavigationView 的 android:layout_gravity="start"属性控制左右滑方向.

DrawerLayout 与 Toolbar 的结合

private DrawerLayout drawer;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_base);    initDrawerLayout();}private void initDrawerLayout() {    // --- DrawerLayout 与 Toolbar 的结合 ---    Toolbar toolbar = findViewById(R.id.toolbar);    setSupportActionBar(toolbar);    drawer = findViewById(R.id.drawer_layout);    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);    drawer.addDrawerListener(toggle);    toggle.syncState();}

返回键的处理

@Overridepublic void onBackPressed() {    if (drawer == null) return;        // 返回键: 侧滑开着就将其关闭, 关着则退出应用     if (drawer.isDrawerOpen(GravityCompat.START)) {        drawer.closeDrawer(GravityCompat.START);    } else {        super.onBackPressed();    }}

打开 / 关闭 / 锁定

// 打开drawer.openDrawer(GravityCompat.START);drawer.openDrawer(GravityCompat.END);drawer.openDrawer(GravityCompat.START, true); // 默认true, 执行动画drawer.openDrawer(navigationView); // 打开指定的 navigationView// 关闭drawer.closeDrawer(GravityCompat.START);drawer.closeDrawers(); // 关闭所有// 打开并锁定drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, GravityCompat.START);
参数 Description
GravityCompat.START 左侧打开
GravityCompat.END 右侧打开
DrawerLayout.LOCK_MODE_LOCKED_CLOSED 关闭锁 (锁着, 不让手势打开)
DrawerLayout.LOCK_MODE_LOCKED_OPEN 开启锁 (开着, 不让手势关闭)
DrawerLayout.LOCK_MODE_UNDEFINED 默认锁 (默认是不上锁)
DrawerLayout.LOCK_MODE_UNLOCKED 不锁 (不上锁)

注意: 使用方向(如: GravityCompat.START) 参数时, 子布局必须有指定layout_gravity属性(如: NavigationView 的 android:layout_gravity="start")与之相匹配, 否则会找不到.

阴影的颜色

// (被遮挡部分的)阴影部分的颜色drawer.setScrimColor(Color.parseColor("#66666666"));

监听滑动事件

drawer.addDrawerListener(drawerListener);private DrawerLayout.DrawerListener drawerListener = new DrawerLayout.DrawerListener() {    @Override    public void onDrawerSlide(@NonNull View view, float v) {        Log.i(TAG, "onDrawerSlide: 滑动时:" + v);    }    @Override    public void onDrawerOpened(@NonNull View view) {        Log.i(TAG, "onDrawerOpened: 打开后");    }    @Override    public void onDrawerClosed(@NonNull View view) {        Log.i(TAG, "onDrawerClosed: 关闭后");    }    @Override    public void onDrawerStateChanged(int i) {        // 滑动状态        switch (i){            case DrawerLayout.STATE_DRAGGING:                Log.i(TAG, "onDrawerStateChanged: 滑动状态");                break;            case DrawerLayout.STATE_IDLE:                Log.i(TAG, "onDrawerStateChanged: 静止状态");                break;            case DrawerLayout.STATE_SETTLING:                // 设置状态在静止状态之前调用, 表示正在调整到最终位置                Log.i(TAG, "onDrawerStateChanged: 设置状态");                break;            default:                break;        }    }};

导航View NavigationView

标准的导航菜单, NavigationView 通常放在 DrawerLayout 中使用.

上部分是Header, 下部分是Menu, 当然这些都是可选的.
Menu具有不错的默认样式: 选中效果 / 分组 / 分组子标题 / Header 等.

DrawerLayout是v4包下的, 而 NavigationView 则是design包下的.

implementation 'com.android.support:design:28.0.0'

添加Header和Menu布局

通过app:headerLayout属性添加Header;
通过app:menu属性添加Menu.

编写Menu布局

Header就是普通的布局没什么好讲的, 这里讲下Menu的编写.

文件放在 res -> menu 文件夹下.

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    tools:showIn="navigation_view">// 有选中效果的菜单组    <group android:checkableBehavior="single">         // 名称        <item            android:id="@+id/nav_gallery"            android:icon="@drawable/ic_menu_gallery"            android:title="Gallery" />        <item            android:id="@+id/nav_slideshow"            android:icon="@drawable/ic_menu_slideshow"            android:title="Slideshow" />        <item            android:id="@+id/nav_manage"            android:icon="@drawable/ic_menu_manage"            android:title="Tools" />    group>// 没有选中效果的普通菜单条目, title子标题    <item android:title="Communicate">        <menu> // 子菜单             // 标题            <item                android:id="@+id/nav_send"                android:icon="@drawable/ic_menu_send"                android:title="Send" />        menu>    item>menu>

设置Menu的选择监听

但用户选择完之后需要手动将侧滑导航栏关闭.

private void intiDrawerView() {    navigationView = findViewById(R.id.nav_view);    navigationView.setNavigationItemSelectedListener(this);}@SuppressWarnings("StatementWithEmptyBody")@Overridepublic boolean onNavigationItemSelected(MenuItem item) {    switch (item.getItemId()) {        case R.id.nav_camera:            break;        case R.id.nav_gallery:            break;        case R.id.nav_slideshow:            break;        case R.id.nav_manage:            break;        case R.id.nav_share:            break;        case R.id.nav_send:            break;        default:            break;    }    // 关闭侧滑导航栏    drawer.closeDrawer(GravityCompat.START);    return true;}

默认的情况下, 用户不点, Menu是没有选中的Item的, 可以通过setCheckedItem(int id)方法设置选中. 且 onNavigationItemSelected是不会回调的.

// 设置第一个选中navigationView.setCheckedItem(R.id.nav_camera);

关于Menu图标的颜色

我选了张彩色的图标:

默认显示的图标:

去除图标颜色显示规则, 显示为原色:

// 去除图标颜色显示规则, 显示为原色navigationView.setItemIconTintList(null);

指定图标颜色显示规则(显示不同颜色):
drawable下创建nav_menu_icon_color选择器资源文件.

// 有-为未选中的颜色, 没有-为选中的颜色int[][] states = new int[][]{new int[]{-android.R.attr.state_checked},new int[]{android.R.attr.state_checked} };int[] colors = new int[]{getResources().getColor(R.color.colorPrimaryDark),  getResources().getColor(R.color.colorAccent) };ColorStateList colorStateList = new ColorStateList(states, colors);navigationView.setItemIconTintList(colorStateList);

指定图标的显示规则(显示不同图标):
// 未找到相关方法, 目前不支持

虽然系统未提供相关方法, 都是你可以通过修改图标自行实现, 就是麻烦些.

// 修改图标navigationView.getMenu().findItem(R.id.nav_camera).setIcon(R.mipmap.menu_caomei);

关于Menu文字的颜色

设置的设置方法与图标是一样的, 这样不展开讲了.

navigationView.setItemTextColor(colorStateList);

更多相关文章

  1. android布局全屏显示,状态栏和导航栏透明设置
  2. 使用setContentView的方式更换布局文件从而更换界面
  3. Android(安卓)圆角图片CircleImageView
  4. android菜瓜笔记之android lint problem
  5. Android之TextSwitcher详解
  6. Android(安卓)ViewPager实例代码介绍2。
  7. android 布局背景模糊化处理
  8. 2013.03.19(4)———activity ListView点击效果实现总结
  9. Android中常见面试题

随机推荐

  1. 世界上有哪些代码量很少,但很牛逼很经典的
  2. LeetCode 题解 | 406 号问题:根据身高重建
  3. 【最新】iPhone X 交互设计官方指南
  4. 如何利用寒假的时间来准备 2020 年的蓝桥
  5. 五分钟学算法:什么是线段树?
  6. Pyecharts 组合图形绘制实践
  7. LeetCode 图解 | 232.使用栈实现队列
  8. 「 LeetCodeAnimation 」动画是如何做出
  9. LeetCode 图解 | 237.删除链表中的节点
  10. 一个我超喜欢的动态博客系统,五分钟即可部