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

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


Android 用 DrawerLayout 和 NavigationView 实现侧滑菜单栏_第1张图片Android 用 DrawerLayout 和 NavigationView 实现侧滑菜单栏_第2张图片



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





    

        

    


    

    

       其实很简单,我们看到最外层是一个 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 文件,代码如下:



    

        
        
        
        
    

      我们首先在 中嵌套了一个 标签,然后将 group 中的 checkableBehavior 属性指定为 single,group 表示一个组,checkableBehavior 指定为 single 表示组中所有菜单项只能单选,这里我们定义了 4 个 item,里面的属性想必我就不用一一介绍了,现在我们就把 menu 准备好了,接下来我们来 headerLayout,这里我们要在 layout 文件夹中创建 navigation_head 文件,代码如下:




    


         这个布局非常简单,就不具体介绍了,这样 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() 方法将滑动菜单关闭

好了到这里就介绍完了,如有错误请指出

 源码地址:点击打开链接



你可能感兴趣的:(【Android,基础】,【Material,Design】,Material,Design,实战)