qq5.0侧滑抽屉式菜单的实现


自己去定义一个SlidingMenu类继承自HorizontalScrollView,主要是在滑动过程中menu和content部分变化的一些动画,透明度啊,缩放之类的。

这里还要导入nineoldandroids-2.4.0.jar.

public class SlidingMenu extends HorizontalScrollView {

	private LinearLayout mWapper;
	private ViewGroup mMenu;
	private ViewGroup mContent;
	private int leftx;
	
	private int mScreenWidth;

	private int mMenuWidth;
	private int mMenuLeftPadding = 80;
	private boolean once = false;
	
	private boolean isOpen = false;
    /**
	 * by lijun
	 * 未使用自定义属性时使用
	 */
	public SlidingMenu(Context context, AttributeSet attrs)
	{
		this(context, attrs, 0);
	}

	public SlidingMenu(Context context, AttributeSet attrs,int defStyle) {
		// TODO Auto-generated constructor stub
		super(context, attrs,defStyle);
		//获取我们定义的属性
		
		TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SildingMenu, defStyle, 0);
		int n = a.getIndexCount();
		for (int i = 0; i < n; i++)
		{
			int attr = a.getIndex(i);
			switch (attr)
			{
			case R.styleable.SildingMenu_rightPadding:
				mMenuLeftPadding =a.getDimensionPixelOffset(attr, 
						(int) TypedValue.applyDimension(
								TypedValue.COMPLEX_UNIT_DIP, 80, context
										.getResources().getDisplayMetrics()));//dp转换为px
				break;
			}
		}
		a.recycle();
		
		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics outMetrics = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(outMetrics);
		mScreenWidth = outMetrics.widthPixels;        //获取屏幕的宽高
		
	}
	public SlidingMenu(Context context) {    //new的时候调用
		// TODO Auto-generated constructor stub
		super(context,null);
	}
	
	/**
	 * by lijun
	 * 设置子View的宽高设置自己的宽高
	 * @return 
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		if(!once)
		{
			mWapper = (LinearLayout)getChildAt(0);
			mMenu = (ViewGroup) mWapper.getChildAt(0);
			mContent = (ViewGroup) mWapper.getChildAt(1);
			mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuLeftPadding;
			mContent.getLayoutParams().width = mScreenWidth;
			once = true;
		}
		
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	/**
	 * by lijun
	 * 通过设置偏移量,将menu隐藏
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		super.onLayout(changed, l, t, r, b);
		if(changed)
		{
		    this.scrollTo(mMenuWidth, 0);
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		int action = ev.getAction();
		int xxxx = (int) ev.getX();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			leftx = xxxx;
			return true;
		case MotionEvent.ACTION_UP:
			int scrollX = getScrollX();
			int lable = scrollX - leftx;
			if(lable>0)
			{
				Log.i("aaaaaaaaa", scrollX+"okokokokok"+leftx);
			   if(scrollX >= mMenuWidth/2)
			   {
				  this.smoothScrollTo(mMenuWidth, 0);   //带有动画效果的移动
				  isOpen = false;
			   }
			   else
			   {
				   this.smoothScrollTo(0, 0);
				   isOpen = true;
			   }
			   return true;
			}
			else
			{   
				this.smoothScrollTo(0, 0);
			}

		default:
			break;
		}
		
		return super.onTouchEvent(ev);
	}
	/**
	 * by lijun
	 * 打开菜单
	 */
	public void openMenu()
	{
		if(isOpen) return;
		this.smoothScrollTo(0, 0);
		isOpen = true;
	}
	public void closeMenu()
	{
		if(!isOpen) return;
		this.smoothScrollTo(mMenuWidth, 0);
		isOpen = false;
	}
	/**
	 * by lijun
	 * 切换菜单
	 */
	public void toggle()
	{
		if(isOpen)
		{
			closeMenu();
		}else
		{
			openMenu();
		}
	}
	/**
	 * by lijun
	 * 滚动发生时
	 */
	protected void onScrollChanged(int l,int t,int oldl,int oldt)
	{
		super.onScrollChanged(l, t, oldl, oldt);
		float scale = l*1.0f/mMenuWidth;   //1-0
		//调用属性动画
		ViewHelper.setTranslationX(mMenu,mMenuWidth*scale);
		
		
		/**主要代码部分
		 * by lijun
		 * 实现抽屉式拖拉
		 * 区别一:内容区域1.0-0。7的缩放效果
		 * scale:1.0-0.0
		 * 0.7+0.3*scale
		 * 区别二:菜单的偏移量需要修改
		 * 区别三:菜单的显示时有缩放以及透明度变化
		 * 缩放:0.7-1.0
		 * 1.0-scale*0.3
		 * 透明度0.6-1.0
		 * 0.6+0.4*(1-scale)
		 */
		float leftScale = 1.0f-0.3f*scale;
		float leftAlpha = 0.5f+0.4f*(1-scale);
		float rightScale = 0.7f+0.3f*scale;
		ViewHelper.setTranslationX(mMenu, mMenuWidth*scale);
		ViewHelper.setScaleX(mMenu, leftScale);
        ViewHelper.setScaleY(mMenu, leftScale);
        ViewHelper.setAlpha(mMenu, leftAlpha);
		ViewHelper.setPivotX(mContent, 0);
		ViewHelper.setPivotY(mContent, mContent.getHeight()/2);  //获取中心点
		ViewHelper.setScaleX(mContent, rightScale);
		ViewHelper.setScaleY(mContent, rightScale);
		
	}
}


原文地址:https://www.cnblogs.com/peterleee/p/9373782.html