Material Design 风格的 Android 侧滑菜单

来源:互联网 发布:java运维面试题 编辑:程序博客网 时间:2024/05/16 05:13

引言

说起这个侧滑菜单,自从QQ改版以后,这个功能是我们每天必见的了,对吧!手势贴最左边,向右滑动就会呼出侧滑菜单的各种功能入口,比如头像资料、钱包、文件、设置等等,还有知乎首页从右往左可以呼出最近浏览记录,很多APP都有这种功能~~


概述

我们都知道Google从发布Android M后,增加一个全新的支持库Android Design Support Library,其中包含了多个重要的 Material Design 组件,可用于将 Material Design 向下兼容到 Android 2.1 (API 7) 。

(1)
在Material Design中,NavigationView 可以方便地创建导航抽屉,被设计于应用导航,它提供了一种通用的导航方式,体现了 Google 设计的一致性。
NavigationView 的典型用途就是配合之前v4包的 DrawerLayout,作为其中的Drawer部分,即导航菜单的本体部分。它只需要接收两个重要的参数:一个用于显示头部的 header 布局(可选),另一个是用于建立导向选项的 menu 菜单。添加完之后,设置监听事件就可以了,更简单高效的实现了导航菜单。
当然,它还提供了不错的默认样式、选中项高亮、分组单选、分组子标题。

(2)
Toolbar 也是在 Android M 开始推出的一个 Material Design 风格的导航控件 ,Google 非常推荐大家使用 Toolbar 来作为客户端的导航栏,以此来取代之前的 Actionbar 。
Toolbar与 Actionbar 相比明显要灵活,它不一定要固定在顶部,可以放到界面的任意位置、还可以设置导航栏图标、设置 APP 的 Logo、支持设置标题和子标题、支持添加一个或多个的自定义控件、支持 Action Menu等等吧。


展示

那么今天就简单介绍一下使用 NavigationView 和 DrawerLayout ,当然还有 Toolbar 绘制最简单的侧滑菜单,效果展示如下:

郭峰的侧滑菜单


开撸

1、既然使用 Design Support Library,首先需要在工程中添加依赖:

compile 'com.android.support:design:24.2.1'

2、 添加后,我们开始写主界面的 Activity,activity_main.xml代码如下:

<?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"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/layout_drawer"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:openDrawer="start">    <android.support.design.widget.CoordinatorLayout        android:id="@+id/drawer_coord"        android:layout_width="match_parent"        android:layout_height="match_parent">        <include layout="@layout/layout_tab" />    </android.support.design.widget.CoordinatorLayout>    <android.support.design.widget.NavigationView        android:id="@+id/view_nav"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_gravity="start"        android:fitsSystemWindows="true"        app:headerLayout="@layout/activity_main_header"        app:menu="@menu/activity_main_drawer" /></android.support.v4.widget.DrawerLayout>

正如你所见,最外层是 DrawerLayout,它分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(DrawerLayout 自身特性),注意的是CoordinatorLayout作用是协调其他组件, 实现联动,怎么具体实现的我暂时也不懂~~ 它里面仅仅 include了一个 Toolbar,当然还有 NavigationView 实现抽屉,里面有俩重要的属性,app:headerLayout 是头布局,app:menu 是菜单资源。

3、附上 include 的 layout_tab.xml 代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <android.support.v7.widget.Toolbar        android:id="@+id/toolbar"        android:layout_width="match_parent"        android:layout_height="?attr/actionBarSize"        android:background="?attr/colorPrimary"        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"        app:layout_scrollFlags="scroll|enterAlways"        app:tabIndicatorColor="@android:color/white"        app:tabIndicatorHeight="4dp" /></LinearLayout>

4、activity_main_header.xml 设置了背景图一张,如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="200dp"    android:background="@mipmap/header"    android:gravity="top"></RelativeLayout>

5、还有 activity_main_drawer.xml代码:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">    <group android:checkableBehavior="single">        <item android:title="@string/app_name">            <menu>                <item                    android:id="@+id/select_city"                    android:icon="@drawable/ic_location"                    android:title="@string/select_city" />                <item                    android:id="@+id/manage_cities"                    android:icon="@drawable/ic_manage_cities"                    android:title="@string/manage_cities" />            </menu>        </item>    </group>    <item android:title="@string/app_name">        <menu>            <item                android:id="@+id/weather_set"                android:icon="@drawable/ic_set"                android:title="@string/weather_set" />            <item                android:id="@+id/weather_about"                android:icon="@drawable/ic_about"                android:title="@string/weather_about" />        </menu>    </item></menu>

易见,这是 menu 资源文件,其中,加一层 group 会有分割线将 group 包裹的内容隔开。

6、最后,就是我们的 MainActivity.java 代码了,如下:

public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener {    Toolbar toolbar;    NavigationView navView;    DrawerLayout drawerLayout;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        toolbar = (Toolbar) findViewById(R.id.toolbar);        navView = (NavigationView) findViewById(R.id.view_nav);        drawerLayout = (DrawerLayout) findViewById(R.id.layout_drawer);        initDrawer();    }    /**     * 初始化抽屉     */    private void initDrawer() {        setSupportActionBar(toolbar);//设定 Toolbar 取代原本的 actionbar        if (navView != null) {            navView.setNavigationItemSelectedListener(this);//设置监听            navView.setItemIconTintList(null);//保持图标本色            //比如布局完成滑出、布局隐藏或者布局正在滑动的时候都会有一个回调的监听事件,            //而ActionBarDrawerToggle就是DrawerLayout事件的监听器            ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(                    this,                    drawerLayout,                    toolbar,                    R.string.navigation_drawer_open,                    R.string.navigation_drawer_close            );            //该方法会自动和actionBar关联, 将开关的图片显示在了actionBar上            toggle.syncState();            drawerLayout.addDrawerListener(toggle);        }    }    @Override    public boolean onNavigationItemSelected(MenuItem item) {        switch (item.getItemId()) {            case R.id.select_city:                //跳转测试                Intent intentSetting = new Intent(MainActivity.this, Main2Activity.class);                startActivity(intentSetting);                break;        }        drawerLayout.closeDrawer(GravityCompat.START);        return true;    }}

逻辑很清晰,首先初始化组件和抽屉设置,最关键的实现接口、重写了 onNavigationItemSelected 方法,通过 getItemId 进行判断点击了 menu 资源布局的哪一个,然后进行相应逻辑处理,最后关闭 drawerLayout。这里仅仅测试了一下 Activity 跳转,Main2Activity 就不说了,更多的按需定制。

7、更多小细节

1)当然 AppTheme 我设置成了 Theme.AppCompat.DayNight.NoActionBar

2)图标资源我是从 阿里巴巴矢量库 下载的 SVG (即 Scalable Vector Graphics 矢量图)图片,在 Studio 转换成 Vector Drawable 进而使用的,简介请往下看。


普及姿势:

Android M 发布的时候,Google 提供了 Vector 的支持,但是 Vector 图像刚发布的时候,是只支持 Android 5.0+ 的,所以说那时候并没有什么卵用。不过自从 AppCompat 23.2 之后,Google 兼容了 Android 2.1 以上的所有系统,只需要引用 com.android.support:appcompat-v7:23.2.0 以上的版本就可以了。这时候,Vector应该算是迎来了它的春天。

Vector Drawable 相对于普通的 Drawable 来说,大概有以下好处:
1、可以自动进行适配。不需要通过分辨率来设置不同的图片。
2、可以大幅减少图像的体积。同样一张图,用 Vector 来实现,可能只有 PNG 的几十分之一。
3、使用简单方便。很多站点、设计工具,都可以直接导出 SVG 图像,从而转换成 Vector 图像。
4、功能强大。少量代码可以实现非常复杂的动画。
5、成熟、稳定,前端使用非常广泛。

SVG 和 Vector Drawable 就说这么一点点,心里有个数就好了,网上好多资源,想深入的可以继续搜索学习。


结束语

哈哈! 技术革新太快了,得紧紧跟着啊,虽然慢了不是一点两点,但是得有向上的心啊~~
今天写这个完全是由于最近在练习写 滴答天气 小项目,想用这效果,才小撸了一下,我也是第一次用,这玩意还是挺简单的把!


0 0
原创粉丝点击