Material Design (一),NavigationView+DrawerLayout轻松实现側拉菜单
前言
Material Design是Google在2014年的I/O大会上推出的全新设计语言。Material Design是基于Android 5.0(API level 21)的,兼容5.0以下的设备时须要使用版本号号v21.0.0以上的support v7包中的appcpmpat,只是遗憾的是support包仅仅支持Material Design的部分特性。使用eclipse或Android Studio进行开发时,直接在Android SDK Manager中将Extras->Android Support Library升级至最新版就可以。眼下最新版本号为:com.android.support:appcompat-v7:23.0.1。
这篇文章将介绍怎样使用设计库里面的一个高级组件NavigationView,使用这个组件加DrawerLayout将非常轻松地实现側拉菜单的效果,而不用像曾经一样自己实现或是引用第三方开源项目实现側拉菜单。
图片效果预览:
NatigationView的使用
上图中的左边部分就是NavigationView,它是一个ViewGroup(子类)。它包含两个部分。一个是头部布局。一个是菜单布局。
通常将这个ViewGroup结合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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- your content layout -->
<FrameLayout
android:layout_width="match_parent"
android:background="#f00"
android:layout_height="match_parent">
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
这基本上就是一个固定的写法,而我们想做的是当用户选择了側拉菜单的菜单后切换右边的内容界面。而内容界面能够使用一个FrameLayout,再加上Fragment就能够实现切换内容视图了。
因为这些控件都在特定的包里,所以须要加入库依赖:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
观察上面的布局文件和图片预览,我们能够发现我们还须要一个头布局和一个菜单文件:
头布局:
<?
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:background="#00f"
android:gravity="center"
android:layout_height="200dp">
<TextView
android:layout_width="wrap_content"
android:text="username"
android:textColor="#fff"
android:layout_height="wrap_content"/>
</LinearLayout>
这个布局文件能够自行改动,自行定制
菜单布局:
<?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/navigation_item_1"
android:checked="true"
android:icon="@mipmap/ic_launcher"
android:title="首页"/>
<item
android:id="@+id/navigation_item_2"
android:icon="@mipmap/ic_launcher"
android:title="新闻">
<menu>
<item
android:id="@+id/navigation_sub_item_1"
android:icon="@mipmap/ic_launcher"
android:title="热点"/>
<item
android:id="@+id/navigation_sub_item_2"
android:icon="@mipmap/ic_launcher"
android:title="体育"/>
<item
android:id="@+id/navigation_sub_item_3"
android:icon="@mipmap/ic_launcher"
android:title="科技"/>
<item
android:id="@+id/navigation_sub_item_4"
android:icon="@mipmap/ic_launcher"
android:title="创业"/>
</menu>
</item>
<item
android:id="@+id/navigation_item_3"
android:checked="true"
android:icon="@mipmap/ic_launcher"
android:title="个人中心"/>
</group>
</menu>
注意:每一个菜单项item
用<group>
标签包裹起来。而且<group>
标签的属性android:checkableBehavior
的值为single
,这就使得側拉菜单为单选模式。同一时候。也能够给每一个菜单加入子菜单,即<item>
标签以下再加入<menu><item>...</item></menu>
,还能够通过<item>
标签的加入属性及值android:checked=”true”来标识该<item>
为选中。
接下来就要在代码中完毕控件的一些设置了
package com.example.lt.meterialdesign;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
final FragmentManager fm = getSupportFragmentManager();
Fragment fragment = new ContentFragment();
Bundle bundle = new Bundle();
bundle.putString("title","首页");
fragment.setArguments(bundle);
fm.beginTransaction().replace(R.id.fl_content,fragment).commit();
final NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
Toast.makeText(MainActivity.this, menuItem.getTitle(), 0).show();
Fragment fragment = new ContentFragment();
Bundle bundle = new Bundle();
bundle.putString("title", menuItem.getTitle().toString());
fragment.setArguments(bundle);
fm.beginTransaction().replace(R.id.fl_content,fragment).commit();
drawerLayout.closeDrawer(Gravity.LEFT);
return false;
}
});
}
}
当中最重要的就是是NavigationView调用setNavigationItemSelectedListener()
设置菜单项选中监听了,这里当用户点击了某个菜单项的时候,将会弹出一个吐司显示选中的菜单的标题。然后用Fragment的视图替换那个内容FrameLayout。最后就是让DrawerLayout自己主动关闭。
ContentFragment.java
package com.example.lt.meterialdesign;
import android.app.ActionBar;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by lt on 2016/3/16.
*/
public class ContentFragment extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
TextView textView = new TextView(getActivity());
if(getArguments()!=null){
String title = getArguments().getString("title");
textView.setText(title);
textView.setGravity(Gravity.CENTER);
textView.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
}
return textView;
}
}
NavigationView组件使用非常easy。以下是本文的效果图:
当然这是左側菜单的情况。假设我们想要实现右側菜单。那也非常easy,仅仅须要将<android.support.design.widget.NavigationView>
的android:layout_gravity
属性值设为right,然后在菜单选择监听中让DrawerLayout选择关闭右側菜单就可以。
因为演示Demo非常easy,仅仅是演示NavigationView这个设计库组件的使用,没有涉及到什么资源,所以这里就不贴上源代码了,有兴趣的能够动手试一下,欢迎拍砖~