且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术

更新时间:2022-08-21 21:04:56



基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术

在附录文章1中,已经在基于第三方的SlidingMenu实现了边侧滑抽屉缩进缩出的效果,接下来,本文针对Google官方边侧滑抽屉技术DrawerLayout,改造DrawerLayout,以实现QQ样式的边侧滑抽屉缩进缩出效果。
关于DrawerLayout的具体实现,在附录文章2中有介绍。
首先写一个DrawerLayout的布局:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic_launcher" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:background="#F44336"
            android:gravity="center"
            android:text="Zhang Phil"
            android:textSize="50sp" />
    </FrameLayout>

    <RelativeLayout
        android:layout_width="200dip"
        android:layout_height="match_parent"
        android:layout_gravity="left" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginTop="20dip"
            android:background="#42a5f5"
            android:gravity="center"
            android:text="左" />
    </RelativeLayout>

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


MainActivity.java,注意MainActivity里面的核心关键处代码:

package zhangphil.drawerlayout;

import com.nineoldandroids.view.ViewHelper;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.view.View;
import android.view.Window;

public class MainActivity extends Activity {

	private DrawerLayout mDrawerLayout;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

		// 故意设置透明,否则在滑动侧滑时候Android的DrawerLayout会在窗口默认显示渐变的灰黑过渡色。
		// 此处屏蔽Android系统提供的默认渐变过渡灰黑
		mDrawerLayout.setScrimColor(Color.TRANSPARENT);

		// mDrawerLayout.setDrawerLockMode(Gravity.LEFT);

		mDrawerLayout.addDrawerListener(new DrawerListener() {

			@Override
			public void onDrawerClosed(View v) {

			}

			@Override
			public void onDrawerOpened(View v) {

			}

			@Override
			public void onDrawerSlide(View drawerView, float slideOffset) {

				// 主体窗口
				View mainFrame = mDrawerLayout.getChildAt(0);

				// 这个就是隐藏起来的边侧滑菜单栏
				View leftMenu = drawerView;

				addQQStyleSlide(mainFrame, leftMenu, slideOffset);
			}

			@Override
			public void onDrawerStateChanged(int arg0) {

			}
		});

	}

	// 实现的核心代码
	private void addQQStyleSlide(View mainFrame, View leftMenu, float slideOffset) {
		float leftScale = 0.5f + 0.5f * slideOffset;
		float rightScale = 1 - 0.2f * slideOffset;

		ViewHelper.setScaleX(leftMenu, leftScale);
		ViewHelper.setScaleY(leftMenu, leftScale);
		ViewHelper.setAlpha(leftMenu, 0.5f + 0.5f * slideOffset);
		ViewHelper.setTranslationX(mainFrame, leftMenu.getMeasuredWidth() * slideOffset);
		ViewHelper.setPivotX(mainFrame, 0);
		ViewHelper.setPivotY(mainFrame, mainFrame.getMeasuredHeight() / 2);
		mainFrame.invalidate();
		ViewHelper.setScaleX(mainFrame, rightScale);
		ViewHelper.setScaleY(mainFrame, rightScale);

		// 该处主要是为了使背景的颜色渐变过渡。
		getWindow().getDecorView().getBackground().setColorFilter(evaluate(slideOffset, Color.BLACK, Color.TRANSPARENT),
				Mode.SRC_OVER);
	}

	private Integer evaluate(float fraction, Object startValue, Integer endValue) {
		int startInt = (Integer) startValue;
		int startA = (startInt >> 24) & 0xff;
		int startR = (startInt >> 16) & 0xff;
		int startG = (startInt >> 8) & 0xff;
		int startB = startInt & 0xff;
		int endInt = (Integer) endValue;
		int endA = (endInt >> 24) & 0xff;
		int endR = (endInt >> 16) & 0xff;
		int endG = (endInt >> 8) & 0xff;
		int endB = endInt & 0xff;
		return (int) ((startA + (int) (fraction * (endA - startA))) << 24)
				| (int) ((startR + (int) (fraction * (endR - startR))) << 16)
				| (int) ((startG + (int) (fraction * (endG - startG))) << 8)
				| (int) ((startB + (int) (fraction * (endB - startB))));
	}
}


代码运行效果(初始化 -> 从左往右逐渐抽屉打开时候的缩进与缩出):

初始化、静止状态

基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术



开始边侧滑,从左边逐渐打开抽屉

基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术



边侧滑结束,抽屉完全打开,此时已经静止

基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术



附录文章:
1,《改进Android SlidingMenu实现QQ样式边侧滑抽屉技术》链接地址:http://blog.csdn.net/zhangphil/article/details/51044699
2,《基于Android官方DrawerLayout实现抽屉导航菜单》链接地址:http://blog.csdn.net/zhangphil/article/details/48710453