Android高级进阶(十)之侧滑菜单2

 自从Android5.0开始Google官方提供了一个全新的侧滑菜单控件叫做NavigationView,用法较之前简单多了。效果图如下:

1. 布局文件

侧滑菜单
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!-- 内容部分 -->
    <FrameLayout
        android:id="@+id/fl"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
         />
    <!-- 菜单部分 -->
    <android.support.design.widget.NavigationView
        android:layout_gravity="start"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        app:menu="@menu/navigation_menu"
        app:headerLayout="@layout/navigation_headerlayout"
        android:background="@android:color/darker_gray"
        />

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

仍就是一个抽屉 布局DrawerLayout,内部有2个子布局FrameLayout与NavigationView分别代表内容部分(点击侧滑菜单项时显示的内容)和侧滑菜单控件。

1.1  侧滑菜单项布局

NavigationView列表项的外观 由属性app:menu="@menu/navigation_menu"来配置。我们需要在layout-menu下创建一个XML文件来定义列表项的外观,布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item 
        android:id="@+id/action_gallery"
        android:title="photos"
        android:orderInCategory="100"
        android:icon="@android:drawable/ic_menu_gallery"
        />
    <item 
        android:id="@+id/action_details"
        android:title="detail"
        android:orderInCategory="100"
        android:icon="@android:drawable/ic_menu_info_details"
        />
    <item 
        android:id="@+id/action_about"
        android:title="about"
        android:orderInCategory="100"
        android:icon="@android:drawable/ic_menu_help"
        />
    <item 
        android:id="@+id/action_music"
        android:title="Music"
        android:orderInCategory="100"
        android:icon="@android:drawable/ic_menu_more"
        >
        <menu >
            <item 
                android:id="@+id/action_play"
		        android:title="play"
		        android:icon="@android:drawable/ic_media_play"/>
            <item 
                android:id="@+id/action_pause"
		        android:title="pause"
		        android:icon="@android:drawable/ic_media_pause"/>
        </menu>
      </item>

</menu>

1.2 侧滑菜单的头部

app:headerLayout="@layout/navigation_headerlayout"用来设置侧滑列表的头部。其中navigation_headerlayout的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:gravity="center_horizontal"
    android:orientation="vertical">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="高小伟"
        android:textSize="30sp" />
</LinearLayout>

2. 代码中如何使用侧滑控件

package com.anyikang.volunteer.sos.swipemenu2;

import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends AppCompatActivity {
	private DrawerLayout drawerlayout;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		drawerlayout = (DrawerLayout)findViewById(R.id.drawerLayout);
		drawerlayout.setDrawerListener(new DrawerLayout.DrawerListener() {

			@Override
			public void onDrawerStateChanged(int newState) {
				// 状态发生改变

			}

			@Override
			public void onDrawerSlide(View drawerView, float slideOffset) {
				// 滑动的过程当中不断地回调 slideOffset:0~1
				View content = drawerlayout.getChildAt(0);
				View menu = drawerView;
				float scale = 1-slideOffset;//1~0
				float leftScale = (float) (1-0.3*scale);
				float rightScale = (float) (0.7f+0.3*scale);//0.7~1
				menu.setScaleX(leftScale);//1~0.7
				menu.setScaleY(leftScale);//1~0.7

				content.setScaleX(rightScale);
				content.setScaleY(rightScale);
				content.setTranslationX(menu.getMeasuredWidth()*(1-scale));//0~width

			}

			@Override
			public void onDrawerOpened(View drawerView) {
				// 打开

			}

			@Override
			public void onDrawerClosed(View drawerView) {
				// 关闭

			}
		});

	}
}

       这里使用serDrawerListener来监听抽屉控件drawerlayout的动作行为,我们主要来看中间这个函数onDrawerSlide,它包含了一个参数slideOffset,这个参数代表了抽屉控件滑出的百分比(也就是侧滑菜单滑出的百分比),例如起初左边侧滑菜单是隐藏的,然后我们滑动屏幕左边缘,侧滑菜单会跟着手指滑动出来,当我们观察到当slideOffset这个值为0.8时,侧滑菜单界面的80%已经展示出来,另外20%的界面仍隐藏在屏幕左侧以外。这说明slideOffset并不是侧滑菜单移动过的像素距离,而是移动过的像素距离dx 占 侧滑菜单整体宽度的一个百分比,它的值是由0-1,即0%-100%,简单的讲就是整个侧滑菜单宽度漏出来的百分比 。

        明白了slideOffset的含义后,我们再来分析以上代码,举个例子,当从屏幕左侧滑出菜单时,slideOffset从0变为1,这时scale的值由1变为0,leftScale的值由0.7变为1。menu.setScaleX, menu.setScaleY会使侧滑菜单的初始大小为原来的70%,然后逐渐扩大到原本的大小,即菜单完整展示出来,与此同时content.setTranslationX逐渐位移内容布局从0(内容布局的原来左边缘)到侧滑菜单的宽度,content.setScaleX,setScaleY会将内容布局逐渐缩放到原来的70%(由完整大小开始逐渐缩小到70%)。这样就实现了我们侧滑菜单时,菜单由小变大,内容布局由大变小并且随着侧滑菜单的滑出逐渐被推到屏幕的右半部分的效果。

  其余的几个监听函数,我相信大家看到函数名就明白了,在此不再赘述,最后按照惯例给出源码下载地址:

https://download.csdn.net/download/gaoxiaoweiandy/10640548

猜你喜欢

转载自blog.csdn.net/gaoxiaoweiandy/article/details/82194256