NavigationDrawer和NavigationView-Android M新控件
Translucent System Bars-4.4新特性
Toolbar-5.0新特性
NavigationDrawer 簡介
NavigationDrawer 是 Google 在 Material Design 中推出的一種側滑導航欄設計風格。說起來很抽象,我們來看下網易云音樂側滑導航欄的實現效果
想有漂亮的 Material Design,Google 已提供 Android Design Support Library 可供使用。它支援 Android 2.1 或以上,提供不少好用的 UI element,可方便做到 Material Design Pattern 的效果。
為了實現這種效果,Google官方推出一個新控件 —— DrawerLayout 。而在 DrawerLayout 沒誕生之前,需求中需要實現側滑導航效果時,我們通常會選擇去選擇一些成熟的第三方開源庫(如最有名的 SlidingMenu)來實現類似的效果。
既然官方有提供,我們為何不使用呢? 不用引入第三方的jar,避免65536(你懂得),還能減少APP的體積,關鍵是使用起來簡單,何樂而不為之呢?
DrawerLayout基本使用
英文666的童鞋可以查看這里How To Make Material Design Navigation Drawer With Header View
一般情況下,在DrawerLayout布局下只會存在兩個子布局:
這兩個布局的關鍵在于 android:layout_gravity屬性的設置。
如果你把其中一個子布局設置成了左側滑菜單,只需要設置 android:layout_gravity=”start” 即可(也可以是left, 右側滑為end或者right)。
沒有設置的布局 自然成為了 內容布局
對,就這么簡單…..按照常規,先上效果圖,然后上code
效果圖
Code
activity_naviation_drawer_base_use.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="match_parent"><android.support.v4.widget.DrawerLayout android:id="@+id/simple_navigation_drawer"android:layout_width="match_parent"android:layout_height="match_parent"><!--內容視圖--><include android:id="@+id/tv_content"layout="@layout/drawer_content_layout"android:layout_width="match_parent"android:layout_height="match_parent" /><!--左側滑菜單欄--><include layout="@layout/drawer_menu_layout"android:layout_width="250dp"android:layout_height="match_parent"android:layout_gravity="start" /><!--右側滑菜單欄--><include layout="@layout/drawer_menu_layout"android:layout_width="250dp"android:layout_height="match_parent"android:layout_gravity="end" /></android.support.v4.widget.DrawerLayout></RelativeLayout>drawer_content_layout.xml
<?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="match_parent"android:orientation="vertical"><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:gravity="center_vertical"android:orientation="horizontal"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="setScrimColor: " /><RadioGroup android:id="@+id/rg_scrim_color"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButton android:id="@+id/rbtn_pink"android:layout_width="wrap_content"android:layout_height="wrap_content"android:drawableLeft="@mipmap/pink" /><RadioButton android:id="@+id/rbtn_green"android:layout_width="wrap_content"android:layout_height="wrap_content"android:drawableLeft="@mipmap/green" /><RadioButton android:id="@+id/rbtn_blue"android:layout_width="wrap_content"android:layout_height="wrap_content"android:drawableLeft="@mipmap/blue" /></RadioGroup></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:gravity="center_vertical"android:orientation="horizontal"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="openDrawer: " /><RadioGroup android:id="@+id/rg_open_drawer"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButton android:id="@+id/rbtn_from_left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="left | start" /><RadioButton android:id="@+id/rbtn_from_right"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="right | end" /></RadioGroup></LinearLayout> </LinearLayout>drawer_menu_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="250dp"android:layout_height="match_parent"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/color_f5f5f5"android:gravity="center"android:text="@string/simple_navigation_drawer" /> </LinearLayout>NaviationDrawerBaseUseAct.java
package com.turing.navigationdrawer;import android.os.Bundle; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; import android.view.Gravity; import android.view.View; import android.widget.RadioGroup; import android.widget.Toast;public class NaviationDrawerBaseUseAct extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener{private DrawerLayout drawerLayout ;private RadioGroup rg_setScrimColor ,rg_openDrawer ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_naviation_drawer_base_use);initView();initEvents();}private void initView() {//DrawerLayoutdrawerLayout = (DrawerLayout) findViewById(R.id.simple_navigation_drawer);//RadioGrouprg_setScrimColor = (RadioGroup) findViewById(R.id.rg_scrim_color);rg_openDrawer = (RadioGroup) findViewById(R.id.rg_open_drawer);}private void initEvents() {//監聽DrawerLayout的側滑drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {@Overridepublic void onDrawerSlide(View drawerView, float slideOffset) {}@Overridepublic void onDrawerOpened(View drawerView) {Toast.makeText(NaviationDrawerBaseUseAct.this, "onDrawerOpened", Toast.LENGTH_SHORT).show();}@Overridepublic void onDrawerClosed(View drawerView) {Toast.makeText(NaviationDrawerBaseUseAct.this, "onDrawerClosed", Toast.LENGTH_SHORT).show();}@Overridepublic void onDrawerStateChanged(int newState) {}});// RadioGroup 監聽事件rg_setScrimColor.setOnCheckedChangeListener(this);rg_openDrawer.setOnCheckedChangeListener(this);}/*** RadioButton被選中后的操作* @param group* @param checkedId*/@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {switch (checkedId){case R.id.rbtn_pink:drawerLayout.setScrimColor(getResources().getColor(R.color.color_e81d62));break;case R.id.rbtn_green:drawerLayout.setScrimColor(getResources().getColor(R.color.color_4bae4f));break;case R.id.rbtn_blue:drawerLayout.setScrimColor(getResources().getColor(R.color.color_2095f2));break;case R.id.rbtn_from_left:drawerLayout.openDrawer(Gravity.LEFT);//打開菜單欄break;case R.id.rbtn_from_right:drawerLayout.openDrawer(Gravity.RIGHT);break;default:break;}} }注意事項
- DrawerLayout 為 v4包中的 android.support.v4.widget.DrawerLayout
- DrawerLayout的監聽事件 new DrawerLayout.DrawerListener(){…}
- Google為我們提供了DrawerLayout常用的API,比如打開或者關閉側滑欄、控制側滑欄的方向、設置滑動時漸變的陰影顏色和監聽滑動事件等,詳見官方API
- DrawerLayout 中的android:layout_width需要設置成match_parent,不能設置成wrap_content,否則會拋出 DrawerLayout must be measured with MeasureSpec.EXACTLY error
- -
效果圖
NavigationView
官方文檔
官方文檔
Represents a standard navigation menu for application. The menu contents can be populated by a menu resource file.
NavigationView is typically placed inside a DrawerLayout.
<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/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"><!-- Your contents --><android.support.design.widget.NavigationView android:id="@+id/navigation"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:menu="@menu/my_navigation_items" /></android.support.v4.widget.DrawerLayout>概述
在Google推出NavigationDrawer設計中,NavigationView和DrawerLayout是官方推薦的最佳組合。
NavigationView是一個導航菜單框架,使用menu資源填充數據,使我們可以更簡單高效的實現導航菜單。它提供了不錯的默認樣式、選中項高亮、分組單選、分組子標題、以及可選的Header.
在使用NavigationView之前,因為它Android Design Support Library(Material Design的兼容包)中,所以我們需要在build.gradle中加入 compile ‘com.android.support:design:23.1.1’
apply plugin: 'com.android.application'android {compileSdkVersion 23buildToolsVersion "23.0.2"defaultConfig {applicationId "com.turing.navigationdrawer"minSdkVersion 10targetSdkVersion 23versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}} }dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])testCompile 'junit:junit:4.12'compile 'com.android.support:appcompat-v7:23.1.1'compile 'com.android.support:design:23.1.1' }引用注意事項:
- 工程配置的 compileSdkVersion 是 23 ,所以需要引入 com.android.support:design:23.x.x 的版本。需要吐槽的是,這里如果你引入了 com.android.support:design:23.1.0 ,工程運行后 NavigationView 會報一個 android.view.InflateException:xxxxxx 的錯誤
運行效果
Code
最主要的兩個屬性分別是:
- app:headerLayout接收一個layout,作為導航菜單頂部的Header,可選項。
- app:menu接收一個menu,作為導航菜單的菜單項,幾乎是必選項,不然這個控件就失去意義了。但也可以在運行時動態改變menu屬性。
- 用于NavigationView的典型menu文件,應該是一個可選中菜單項的集合。其中checked=”true”的item將會高亮顯示,這可以確保用戶知道當前選中的菜單項是哪個。item的選中狀態也可以在代碼中設置。
activity_navigation_view_base_use.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"android:id="@+id/drawer"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/color_31c27c"><LinearLayout android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="NavigationDrawerContent" /></LinearLayout><android.support.design.widget.NavigationView android:id="@+id/navigation_view"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:headerLayout="@layout/navigation_drawer_header"app:menu="@menu/navigation_drawer_menu" /></android.support.v4.widget.DrawerLayout>navigation_drawer_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="250dp"android:background="@color/color_512da8"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"android:layout_margin="10dp"android:text="HeaderLayout"android:textColor="@android:color/white"android:textSize="18sp" /> </RelativeLayout>menu/navigation_drawer_menu.xml
在menu目錄下
<?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/item_green"android:icon="@mipmap/green"android:title="Green" /><item android:id="@+id/item_blue"android:icon="@mipmap/blue"android:title="Blue" /><item android:id="@+id/item_pink"android:icon="@mipmap/pink"android:title="Pink" /></group><item android:title="SubItems"><menu><item android:id="@+id/subitem_01"android:icon="@mipmap/ic_launcher"android:title="SubItem01" /><item android:id="@+id/subitem_02"android:icon="@mipmap/ic_launcher"android:title="SubItem02" /><item android:id="@+id/subitem_03"android:icon="@mipmap/ic_launcher"android:title="SubItem03" /></menu></item><item android:title="SubItems"><menu><item android:id="@+id/subitem_04"android:icon="@mipmap/ic_launcher"android:title="SubItem04" /><item android:id="@+id/subitem_05"android:icon="@mipmap/ic_launcher"android:title="SubItem05" /><item android:id="@+id/subitem_06"android:icon="@mipmap/ic_launcher"android:title="SubItem06" /></menu></item> </menu>NavigationViewBaseUseAct.java
package com.turing.navigationdrawer;import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; import android.view.Window; import android.widget.Toast;public class NavigationViewBaseUseAct extends AppCompatActivity {private DrawerLayout drawerLayout;private NavigationView navigationView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);supportRequestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_navigation_view_base_use);drawerLayout = (DrawerLayout) findViewById(R.id.drawer);navigationView = (NavigationView) findViewById(R.id.navigation_view);//設置菜單圖標恢復本來的顏色,不設置的話 是沒有顏色的......navigationView.setItemIconTintList(null);// 設置監聽事件navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(MenuItem item) {switch (item.getItemId()){case R.id.subitem_01:Toast.makeText(NavigationViewBaseUseAct.this, "sub item 01", Toast.LENGTH_SHORT).show();break;default:break;}// 關閉drawerlayoutdrawerLayout.closeDrawers();return true;}});} }注意事項:
-第一次運行代碼的時候,圖標的顏色居然都是灰色的….代碼中可以調用下面這個APInavigationView.setItemIconTintList(null);//設置菜單圖標恢復本來的顏色
- NavigationView 基本已經規定設置好了大小距離,留給我們可以改動的空間并不多。詳見官方文檔(自備梯子)如果你想調整一下菜單的布局寬高之類的,基本是不可能的了
仿網易云音樂的 NavigationDrawer 實現
官方運行圖
里面的圖標,可以下載APP,解壓后,去文件夾里取出來~
主要就是一個線性布局的菜單并結合了 Translucent System Bar 的特性。
Code
activity_cloud_music.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/drawer"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/color_cd3e3a"><LinearLayout android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="65dp"android:background="@color/color_cd3e3a"android:gravity="center"android:text="網易云音樂"android:textColor="@android:color/white"android:textSize="18sp" /><LinearLayout android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/white"android:orientation="vertical"></LinearLayout></LinearLayout><LinearLayout android:id="@+id/navigation_view"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="start"android:background="@android:color/white"android:fitsSystemWindows="true"android:orientation="vertical"><ImageView android:layout_width="match_parent"android:layout_height="180dp"android:scaleType="centerCrop"android:src="@mipmap/topinfo_ban_bg" /><LinearLayout android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageView android:layout_width="40dp"android:layout_height="40dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:src="@mipmap/topmenu_icn_msg" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我的消息"android:textColor="@android:color/black"android:textSize="15sp" /></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageView android:layout_width="40dp"android:layout_height="40dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:src="@mipmap/topmenu_icn_store" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="積分商城"android:textColor="@android:color/black"android:textSize="15sp" /></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageView android:layout_width="40dp"android:layout_height="40dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:src="@mipmap/topmenu_icn_member" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="付費音樂包"android:textColor="@android:color/black"android:textSize="15sp" /></LinearLayout><LinearLayout android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageView android:layout_width="40dp"android:layout_height="40dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:src="@mipmap/topmenu_icn_free" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="在線聽歌免流量"android:textColor="@android:color/black"android:textSize="15sp" /></LinearLayout></LinearLayout> </android.support.v4.widget.DrawerLayout>沉浸式主題樣式,需要在不同SDK的values目錄下,設置樣式,在Manifest.xml中通過 android:theme引用主題,別忘了 android:fitsSystemWindows=”true”。
效果圖
左上角的導航動畫效果實現
效果
ActionBarDrawerToggle實現
之前想要引入這種效果,都是來自第三方的開源代碼,諸如下面兩個比較有名的:
- LDrawer
- android-ui
自從MaterialDesign出來之后,就再也需要了,Google提供了ActionBarDrawerToggle
activity_animation_left_top.xml
<?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="match_parent"android:orientation="vertical"><android.support.v7.widget.Toolbar android:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/colorPrimary"android:minHeight="?attr/actionBarSize"android:theme="@style/Theme.Drawer.ArrowAnimation" /><android.support.v4.widget.DrawerLayout android:id="@+id/drawer"android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="NavigationAnimation" /><LinearLayout android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="start"android:background="@android:color/white"android:orientation="vertical"><TextView android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="Drawer" /></LinearLayout></android.support.v4.widget.DrawerLayout> </LinearLayout>AnimationLeftTopAct.java
package com.turing.navigationdrawer;import android.content.res.Configuration; import android.os.Bundle; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.view.Window;public class AnimationLeftTopAct extends AppCompatActivity {private Toolbar mToolbar;private DrawerLayout mDrawerLayout;private ActionBarDrawerToggle mActionBarDrawerToggle;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);supportRequestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_animation_left_top);mToolbar = (Toolbar) findViewById(R.id.toolbar);mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);mActionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.open, R.string.close);mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);}@Overrideprotected void onPostCreate(Bundle savedInstanceState) {super.onPostCreate(savedInstanceState);mActionBarDrawerToggle.syncState();}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {if (mActionBarDrawerToggle.onOptionsItemSelected(item)) {return true;}return super.onOptionsItemSelected(item);}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);mActionBarDrawerToggle.onConfigurationChanged(newConfig);} }material-menu 開源的動畫效果
material-menu
比 NavigationView 更好的選擇
MaterialDrawer
參考文章:http://www.jianshu.com/p/c8cbeb7ea43a#
感謝D_clork
總結
以上是生活随笔為你收集整理的NavigationDrawer和NavigationView-Android M新控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Toolbar-5.0新特性
- 下一篇: Android Design Suppo