Android 实现滑动的侧栏菜单

实现一个简单的侧栏菜单,类似于QQ。

DragViewGroup.class

public class DragViewGroup extends FrameLayout {

	private ViewDragHelper mViewDragHelper;
	private View mMenuView, mMainView;
	private int mWidth;

	public DragViewGroup(Context context) {
		super(context);
		initView();
	}

	public DragViewGroup(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView();
	}

	public DragViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView();
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		mMenuView = getChildAt(0);
		mMainView = getChildAt(1);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		mWidth = mMenuView.getMeasuredWidth();
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		return mViewDragHelper.shouldInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 将触摸事件传递给ViewDragHelper,此操作必不可少
		mViewDragHelper.processTouchEvent(event);
		return true;
	}

	private void initView() {
		mViewDragHelper = ViewDragHelper.create(this, callback);
	}

	private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {

		// 何时开始检测触摸事件
		@Override
		public boolean tryCaptureView(View child, int pointerId) {
			// 如果当前触摸的child是mMainView时开始检测
			return mMainView == child;
		}

		// 触摸到View后回调
		@Override
		public void onViewCaptured(View capturedChild, int activePointerId) {
			super.onViewCaptured(capturedChild, activePointerId);
		}

		// 当拖拽状态改变,比如idle,dragging
		@Override
		public void onViewDragStateChanged(int state) {
			super.onViewDragStateChanged(state);
		}

		// 当位置改变的时候调用,常用与滑动时更改scale等
		@Override
		public void onViewPositionChanged(View changedView, int left, int top,
				int dx, int dy) {
			super.onViewPositionChanged(changedView, left, top, dx, dy);
		}

		// 处理垂直滑动
		@Override
		public int clampViewPositionVertical(View child, int top, int dy) {
			return 0;
		}

		// 处理水平滑动
		@Override
		public int clampViewPositionHorizontal(View child, int left, int dx) {
			if (left > 0) {
				// 如果手势向右滑动则返回,如果向左滑动不返回				
				return left;
			}
			return 0;
		}

		// 拖动结束后调用
		@Override
		public void onViewReleased(View releasedChild, float xvel, float yvel) {
			super.onViewReleased(releasedChild, xvel, yvel);
			// 手指抬起后缓慢移动到指定位置
			if (mMainView.getLeft() < 500) {
				// 关闭菜单
				// 相当于Scroller的startScroll方法
				mViewDragHelper.smoothSlideViewTo(mMainView, 0, 0);
				ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
			} else {
				// 打开菜单
				mViewDragHelper.smoothSlideViewTo(mMainView, 300, 0);
				ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
			}
		}
	};

	@Override
	public void computeScroll() {
		if (mViewDragHelper.continueSettling(true)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}
}
drag_viewgroup.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.view.DragViewGroup
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/blue" >

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Menu" />
        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/gray" >

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Main" />
        </FrameLayout>
    </com.example.view.DragViewGroup>

</FrameLayout>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值