Android仿网易client实现抽屉式拖拉菜单界面

前面有写过一篇文章使用DrawerLayout实现Android仿网易client抽屉模式,昨天从群里看一哥们问抽屉式拖拉,从主界面的下方出现,而使用DrawerLayout实现的是覆盖掉主界面,今天我们就来实现一下主界面下方脱出菜单界面,先上图,方便观看


啊哦,图片好大,開始今天的实现


1.继承HorizontalScrollView,实现自己定义控件

package com.sdufe.thea.guo.view;

import com.nineoldandroids.view.ViewHelper;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class SlidingMenu extends HorizontalScrollView {

	private LinearLayout mWapper;
	private ViewGroup mMenu;
	private ViewGroup mContent;
	/**
	 * 屏幕宽度
	 */
	private int mSreenWidth;
	/**
	 * 菜单距离右側的宽度,单位dp
	 */
	private int mMenuRightPadding=100;
	/**
	 * 菜单宽度
	 */
	private int mMenuWidth;
	/**
	 * 确定onMeasure仅仅绘制一次
	 */
	private boolean once;

	public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		WindowManager windowManager = (WindowManager) context
				.getSystemService(context.WINDOW_SERVICE);
		DisplayMetrics outMetrics=new DisplayMetrics();
		windowManager.getDefaultDisplay().getMetrics(outMetrics);
		mSreenWidth=outMetrics.widthPixels;
		
		/**
		 * 把dp转化成px
		 */
		mMenuRightPadding = (int) TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 100, getResources()
						.getDisplayMetrics());
	}

	public SlidingMenu(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SlidingMenu(Context context) {
		this(context, null);
	}
	/**
	 * 确定宽高
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		if (!once) {
			mWapper=(LinearLayout) getChildAt(0);
			mMenu=(ViewGroup) mWapper.getChildAt(0);
			mContent=(ViewGroup) mWapper.getChildAt(1);
			/**
			 * 菜单设置宽度
			 */
			mMenuWidth=mMenu.getLayoutParams().width=mSreenWidth-mMenuRightPadding;
			/**
			 * 内容设置宽度
			 */
			mContent.getLayoutParams().width=mSreenWidth;
			once=true;
		}
	}
	
	/**
	 * 设置偏移量,隐藏menu
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed) {
			/**
			 * 瞬间完毕隐藏
			 */
			this.scrollTo(mMenuWidth, 0);
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_UP:
			/**
			 * 隐藏部分宽度
			 */
			int scroll=getScrollX();
			if (scroll>mMenuWidth/2) {
				/**
				 * 动画实现隐藏
				 */
				smoothScrollTo(mMenuWidth, 0);
			}else {
				/**
				 * 动画实现显示
				 */
				smoothScrollTo(0, 0);
			}
			return true;
		}
		return super.onTouchEvent(ev);
	}
	/**
	 * 通过onScrollChanged实现抽屉式滑动
	 */
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		
		ViewHelper.setTranslationX(mMenu, l);
	}
}

在构造函数中获得屏幕的宽度以及将dp为单位的mMenuRightPadding转化为px

onMeasure中给宽高赋值

onLayout中确定位置

onTouch中控制手势

onScrollChanged实现抽屉式动画,这里引用了nineold动画包,兼容3.0一下版本号

剩余的部分代码中凝视都说的非常清楚了,这里就不在扯淡了,到此几乎相同就实现了,以下就是使用了,

<com.sdufe.thea.guo.view.SlidingMenu 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" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <include layout="@layout/layout_menu" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/monkey"
            android:orientation="vertical" >
        </LinearLayout>
    </LinearLayout>

</com.sdufe.thea.guo.view.SlidingMenu>

ok,结束,以上代码改动自鸿洋的qq側滑,略有不同而已


代码下载地址:http://download.csdn.net/detail/elinavampire/8276537


原文地址:https://www.cnblogs.com/wgwyanfs/p/6830472.html