Android 用 DrawerLayout 和 NavigationView 实现侧滑菜单栏

xiaoxiao2021-02-27  163

       这是我们 Material Design 系列的第三篇文章了,今天我们来谈谈侧滑菜单,侧滑菜单是很多 APP 中常见的功能效果,今天我们将介绍使用 Material Design 中的 DrawerLayout 和 NavigationView 相结合来实现侧滑栏菜单效果,借助 Google 提供的这些工具实现侧滑的功能将变得异常的简单,侧滑菜单可以将菜单选项隐藏起来,然后可以通过滑动的方式来显示,这样很好的节省了手机屏膜的空间,这也是 Material Design 设计中非常推荐的做法,例如谷歌邮箱 Gmail 就使用了这种设计,接下来我们就来具体的实现这种非常常见的效果,我们先来上效果图吧

下面我们来看一下实现如上界面的布局代码:

<?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" android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#c7c6c6"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.Toolbar android:id="@+id/toolBar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:titleTextColor="#f5f0f0" /> </RelativeLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="left" app:headerLayout="@layout/navigation_head" app:menu="@menu/navigation"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>

       其实很简单,我们看到最外层是一个 DrawerLayout 控件,是由 suppout-v4 库提供的,首先它是一个布局,在布局中容许放置两个直接的子控件,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容

       我们这里放了两个子控件:一个相对布局,然后放置了我们上一次分享的 ToolBar 控件,另一个子控件这里使用了一个NavigationView,其实这里放什么都可以,DrawerLayout 并没有限制使用固定的控件,这里需要注意的是,关于第二个控件,layout_gravity 这个属性是必须制定的,因为我们要告诉 DrawerLayout 滑动菜单是在屏膜的左边还是右边

left 表示滑动菜单在左边right 表示滑动菜单在右边start 表示会根据系统语言进行判断 这里我们指定了left,从屏膜左边滑出        想必到这里大家该问第二个控件为什么是使用 NavigationView 了,接下来我们来简单介绍下 NavigationView,事实上,你可以在滑动菜单页面自己定制任意的布局,但是谷歌给我们提供了一种更好的方法,那就是使用 NavigationView,NavigationView 也是 Design Support 库中提供的一个控件,是严格按照 Material Design 风格来设计的,使我们实现滑动菜单页面更加的简单,下面我们就来介绍如何使用 NavigationView 首先需要在 app/build.gradle 文件中引入 Design Support 库: dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' compile 'com.android.support:design:25.1.0' } 然后在使用 NavigationView 之前我们还需要准备两个东西:menu 和 headerLayout,menu 是用来在 NavigationView 中显示具体的菜单项的,headerLayout 是用来在 NavigationView 中显示头布局的 然后我们在 menu 文件夹中创建 navigation 文件,代码如下: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/account" android:icon="@mipmap/account" android:title="account" /> <item android:id="@+id/attachment" android:icon="@mipmap/attachment" android:title="attachment" /> <item android:id="@+id/edit" android:icon="@mipmap/edit" android:title="edit" /> <item android:id="@+id/set" android:icon="@mipmap/set" android:title="set" /> </group> </menu>       我们首先在 <menu> 中嵌套了一个 <group> 标签,然后将 group 中的 checkableBehavior 属性指定为 single,group 表示一个组,checkableBehavior 指定为 single 表示组中所有菜单项只能单选,这里我们定义了 4 个 item,里面的属性想必我就不用一一介绍了,现在我们就把 menu 准备好了,接下来我们来 headerLayout,这里我们要在 layout 文件夹中创建 navigation_head 文件,代码如下: <?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="160dp" android:background="#7dd1f0" android:gravity="center" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="head layout" android:textSize="40dp" /> </LinearLayout>          这个布局非常简单,就不具体介绍了,这样 headerLayout 布局文件我们就创建好了,然后再通过如下两行代码把我们准备好的 menu 和 headerLayou 设置进去: app:headerLayout="@layout/navigation_head" app:menu="@menu/navigation"> 到这里我们的 NavigationView 就设置完成了 接下来我们去完善 MainActivity 中的代码如下:        为了让用户知道屏膜的边缘是可以拖动的,MD 的做法是建议在 ToolBar 的最左侧加入一个导航按钮,点击按钮也会将滑动菜单的内容展示出来,下面我们来实现这个功能,首先我们准备了一张 category.png 图标,放在 mipmap 目录下,然后修改 MainActivity 中的代码如下: /** * NavigationView 侧滑栏 */ public class MainActivity extends AppCompatActivity { private DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar); setSupportActionBar(toolbar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); ActionBar actionBar = getSupportActionBar(); if (actionBar!=null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.mipmap.category); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.backup: Toast.makeText(this, "Click Backup", Toast.LENGTH_LONG).show(); break; case R.id.delete: Toast.makeText(this, "Click Delete", Toast.LENGTH_LONG).show(); break; case R.id.setting: Toast.makeText(this, "Click Setting", Toast.LENGTH_LONG).show(); break; case android.R.id.home: mDrawerLayout.openDrawer(Gravity.LEFT); break; default: } return true; } }        这里我们首先调用 findViewById() 方法得到了 DrawerLayout 的实例,然后调用 getSupportActionBar() 方法得到了 ActionBar 的实例,这个 ActionBar 的具体体现是由 ToolBar 来实现的,接着调用 ActionBar 的 setDisplayHomeAsUpEnabled() 方法让导航按钮显示出来,又调用 setHomeAsUpIndicator() 方法来设置一个导航按钮图标,接下来我们在 onOptionsItemSelected() 方法中对导航按钮进行点击事件的处理,导航按钮的 id 永远都是 android.R.id.home,然后调用 DrawerLayout 的 openDrawer() 方法将滑动菜单展示出来,注意这里 openDrawer() 方法要求传入一个 Gravity 参数,这里我们保持和 xml 中的一致,传入 Gravity.LEFT 接下来我们需要去处理 NavigationView 中菜单项的点击事件了,接着修改 MainActivity 中的代码如下: /** * NavigationView 侧滑栏 */ public class MainActivity extends AppCompatActivity { private DrawerLayout mDrawerLayout; private NavigationView navigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar); setSupportActionBar(toolbar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); navigationView = (NavigationView) findViewById(R.id.navigation); ActionBar actionBar = getSupportActionBar(); if (actionBar!=null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeAsUpIndicator(R.mipmap.category); } navigationView.setCheckedItem(R.id.account); navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { mDrawerLayout.closeDrawers(); //do something return true; } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.backup: Toast.makeText(this, "Click Backup", Toast.LENGTH_LONG).show(); break; case R.id.delete: Toast.makeText(this, "Click Delete", Toast.LENGTH_LONG).show(); break; case R.id.setting: Toast.makeText(this, "Click Setting", Toast.LENGTH_LONG).show(); break; case android.R.id.home: mDrawerLayout.openDrawer(Gravity.LEFT); break; default: } return true; } }               代码比较简单,这里我们同上还是先获取到 NavigationView 的实例,然后调用它的 setCheckedItem() 方法将 account 菜单项来设置为默认选项,接着调用了 setNavigationItemSelectedListener() 方法来设置一个菜单项中的事件监听器,当用户点击任意菜单项时,会回调 onNavigationItemSelected() 方法,我们可以在这个方法中写相应的逻辑,具体内容还需要大家自己完成,这里调用了closeDrawers() 方法将滑动菜单关闭 好了到这里就介绍完了,如有错误请指出  源码地址:点击打开链接

转载请注明原文地址: https://www.6miu.com/read-12853.html

最新回复(0)