Material Design最佳体验(3):使用DrawerLayout、NavigationView轻松实现滑动菜单

本文详细介绍使用DrawerLayout和NavigationView实现Android应用中的滑动菜单功能。不仅提供了详细的代码示例,还介绍了如何设置滑动菜单的监听器以及NavigationView的具体配置方法。

                           Material Design最佳体验(3):

使用DrawerLayout、NavigationView轻松实现滑动菜单

 

   作者:             

 蒋东国

   时间:

  2017年03月11日 星期六                                                      

  应用来源:

  路痴宝v1.2

  博客地址:

 http://blog.youkuaiyun.com/andrexpert/article/details/61429929

      

       情景再现“Material Design是Google在2014年的I/O大会提出的一套全新的界面设计语言,它包含了视觉、运动、互动效果等特性,其宗旨就是解决Android平台界面风格不统一的问题。虽然Material Design是一套界面设计语言,但为了方便APP开发,Google提供了一个Design Support库,这个库对一些常见的控件和效果进行了封装,使开发工程师在在不了解Material Design的情况下能够将自己的应用Material化。”

       滑动菜单是Material Design中最常见的效果之一,所谓滑动菜单就是将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后可以通过滑动的方式将菜单显示出来。如果是自己去实现的话,难度应该比较大,还好谷歌提供了一个DrawerLayout控件,使用这个控件我们可以非常轻松地实现滑动菜单。当然,在上干货之前,我们先看下QQ的侧滑菜单来直观感受下:


      好了,接下来我们就开始讲解如何使用DrawerLayout和NavigationView来实现一个滑动菜单。DrawerLayout是实现滑动菜单的核心类,是support-v4库提供的一个布局控件,在使用时我们需要引入support-v4包。它的使用非常简单,只需要将Acitivity布局的最外层替换成DrawerLayout,然后放置二个或三个直接子控件即可,其中第一个是用作于主屏幕的中显示的内容,另外两个就分别为左、右滑动菜单布局。activity_main.xml布局代码如下:

<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/main_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/img_frame_background" >

    <!-- 主页 -->

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <android.support.v7.widget.Toolbar
            android:id="@+id/main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <ListView
            android:id="@+id/main_list_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#FFFFFF"
            android:layout_below="@id/main_toolbar" />
    </RelativeLayout>
	<!--左侧滑动菜单布局-->
	<TextView
        android:id="@+id/left_sliding_tv "
        android:name="jiangdg.meterial.demosliding.LeftSidingFragment"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:tag=" LEFT " />
	<!--右侧滑动菜单布局-->
	 <fragment
        android:id="@+id/right_sliding_fragment"
        android:name="jiangdg.meterial.demosliding.LeftSidingFragment"
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:tag=" RIGHT " />
</android.support.v4.widget.DrawerLayout>
      对于DrawerLayout来说,主要是通过android:layout_gravity="start"或android:layout_gravity="end"来指定左右滑动菜单的布局,该布局可以为一个view控件,也可以为一个ViewGroup控件或者fragment。如果滑动菜单为fragment时,还需要添加android:name属性指定相应的Fragment实现类。右侧滑动菜单的Fragment实现类RightSidingFragment.class完整代码如下:

/**
 * 左侧滑动菜单Fragment
 * 
 * @author Created by jiangdongguo on 2017-2-22下午11:11:58
 *
 * Blog:http://blog.youkuaiyun.com/andrexpert
 * MyApp:http://www.anzhi.com/soft_2729689.html(安智市场)
/
public class RightSidingFragment extends Fragment {
	private LinearLayout mSaoLayout;
	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.layout_right, null);
		findViews(view);
		return view;
	}

	private void findViews(View view) {
		mSaoLayout = (LinearLayout)view.findViewById(R.id.saosao_layout);
		mSaoLayout.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				MainActivity a = (MainActivity)getActivity();
				a.closeLeftDrawer();
			}
		});
	}
}

     既然DrawerLayout是一个布局控件,那么首先肯定是通过findViewById来获得实例,然后调用DrawerLayout的openDrawer(Gravity gravity)方法和closeDrawer(Gravity gravity)方法来实现展开或关闭滑动菜单,左右方向由Gravity.START和Gravity.END参数决定,最后也可以使用DrawerLayout的setDrawerListener方法来对滑动菜单的展开状态事件进行监听。MainActivity.class完整代码如下:

/**滑动菜单Demo
 *
 * @author Created by jiangdongguo on 2017-3-11下午9:16:56
 *
 * Blog:http://blog.youkuaiyun.com/andrexpert
 * MyApp:http://www.anzhi.com/soft_2729689.html(安智市场)
/
public class MainActivity extends ActionBarActivity {
	private static final String TAG = "MainActivity";
	private DrawerLayout mDrawerLayout;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initToolbar();
		initDrawerLayout();
		
		ListView mListView = (ListView)findViewById(R.id.main_list_view);
		List<String> mList = new ArrayList<String>();
		for(int i=0;i<20;i++){
			String content = "测试-->"+i;
			mList.add(content);
		}
		ArrayAdapter< String> mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,mList);
		mListView.setAdapter(mAdapter);
	}
	

	private void initToolbar() {
		// 替换标题栏为Toolbar
		Toolbar mToolbar = (Toolbar) findViewById(R.id.main_toolbar);
		setSupportActionBar(mToolbar);
		// 使能Home按键
		ActionBar actionbar = getSupportActionBar();
		if(actionbar != null){
			actionbar.setDisplayHomeAsUpEnabled(true);
			actionbar.setHomeButtonEnabled(true);
		}
	}

	private void initDrawerLayout() {
		mDrawerLayout = (DrawerLayout)findViewById(R.id.main_drawer_layout);
		//为滑动菜单注册事件监听器
		mDrawerLayout.setDrawerListener(new DrawerListener() {		
			@Override
			public void onDrawerStateChanged(int arg0) {
				Log.i(TAG, "onDrawerStateChanged");
			}

			@Override
			public void onDrawerSlide(View drawView, float slideOffset) {
                                 Log.i(TAG, " onDrawerSlide");
			}
			
			@Override
			public void onDrawerOpened(View arg0) {
				Log.i(TAG, "onDrawerOpened");
			}
			
			@Override
			public void onDrawerClosed(View arg0) {
				Log.i(TAG, "onDrawerClosed");
			}
		});
		
		//实例化左侧滑动菜单
		TextView mTvLeftDrawer = (TextView)findViewById(R.id.left_sliding_tv);
		mTvLeftDrawer.setText("中华人民共和国,万岁!");
	}
	
	public void openLeftDrawer(){
		//打开左侧滑动菜单
		mDrawerLayout.openDrawer(Gravity.START);
	}
	
	public void openRightDrawer(){
		//打开右侧滑动菜单
		mDrawerLayout.openDrawer(Gravity.END);
	}
	
	public void closeLeftDrawer() {
		//关闭所有滑动菜单
		mDrawerLayout.closeDrawers();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.home:
			openLeftDrawer();
			break;
		case R.id.menu_more:
			openRightDrawer();
			break;
		default:
			break;
		}
		return true;
	}
}
   运行效果如下:

  

       目前我们已经成功实现了滑动菜单功能,并且滑动的效果是非常流畅,可见DrawerLayout控件之强大。但是相比于QQ的侧滑效果,上面实现的左侧滑动菜单布局却显得非常单调,当然,我们也可以使用fragment或者在主布局中设计成QQ侧滑菜单那样,但实际实现起来还是有点复杂。好在Google在提供DrawerLayout轻松实现侧滑菜单,又为我们提供了一个设计侧滑菜单布局的控件- NavigationView。NavigationView是Design Support库中提供的一个控件,它不仅是严格按照Material Design的要求来进行设计的,而且还可以将滑动菜单页面的实现变得非常简单。接下来,我们就将activity_main.xml文件中左侧滑动菜单的布局替换为NavigationView,完整代码如下:

<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/main_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/img_frame_background" >

    <!-- 主页 -->

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <android.support.v7.widget.Toolbar
            android:id="@+id/main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <ListView
            android:id="@+id/main_list_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/main_toolbar"
            android:background="#FFFFFF" />
    </RelativeLayout>
    <!-- 左侧滑动菜单 -->

    <android.support.design.widget.NavigationView
        android:id="@+id/main_left_sliding_nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu" />

</android.support.v4.widget.DrawerLayout>

分析:NavigationView控件的使用非常简单,只需将原来左侧滑动菜单的TextView替换成NavigationView即可,然后通过android:layout_gravity="start"属性指定是那一侧滑动菜单,最后通过app:headerLayout="@layout/nav_header"和app:menu="@menu/nav_menu"分别指定滑动菜单布局的头部界面和内容界面。其中,nav_header.xml位于layout目录下,nav_menu.xml位于menu目录下,分别为:

(1)   res/layout/nav_header.xml

 

(2)  res/menu/nav_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 菜单组形式,每次只能选中一个item -->
    <group android:checkableBehavior="single" >
        <item
            android:id="@+id/nav_menu_qianbo"
            android:icon="@drawable/more_qianbo"
            android:title="QQ钱包"/>
        <item
            android:id="@+id/nav_menu_zhuangbao"
            android:icon="@drawable/more_zhuangbao"
            android:title="个性装扮"/>
        <item
            android:id="@+id/nav_menu_shouchang"
            android:icon="@drawable/menu_shouchang"
            android:title="我的收藏"/>
        <item
            android:id="@+id/nav_menu_xiangce"
            android:icon="@drawable/menu_xiangce"
            android:title="我的相册"/>
    </group>

</menu>

   码字不易,转载请声明出处:http://blog.youkuaiyun.com/andrexpert/article/details/61429929


  (.......未完,内容还比较多,明天接着写。。。)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值