Android(安卓)NavigationDrawer(侧滑导航栏 DrawerLayout + NavigationView)
Android NavigationDrawer(侧滑导航栏 DrawerLayout + NavigationView)
本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/90487113
Google官方出品的侧滑导航栏, 可替换长期未维护的SlidingMenu.
除此之外, 还有个第三方开源库MaterialDrawer可供选择
Navigation Drawer
是 Material Design
中的侧滑导航栏, 由抽屉布局 DrawerLayout
和 导航View NavigationView
组成.
快速创建
- 新建项目时:
- 新建项目时, 最后一页"Add an Activity to Mobile" 选择
Navigation Drawer Activity
- 新建项目时, 最后一页"Add an Activity to Mobile" 选择
- 新建Activity时:
- 在已有的项目, 创建Activity选择
Navigation Drawer Activity
- 在已有的项目, 创建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);
更多相关文章
- android布局全屏显示,状态栏和导航栏透明设置
- 使用setContentView的方式更换布局文件从而更换界面
- Android(安卓)圆角图片CircleImageView
- android菜瓜笔记之android lint problem
- Android之TextSwitcher详解
- Android(安卓)ViewPager实例代码介绍2。
- android 布局背景模糊化处理
- 2013.03.19(4)———activity ListView点击效果实现总结
- Android中常见面试题