您的位置:首页 > 其它

读书笔记之类似qq的侧滑菜单

2016-04-14 20:54 302 查看
        其实现在有很多第三方开源组件,大家觉得方便就会拿来用,而对其原理却不是很懂,以至于看源码都可能看不到,下面就讲一下简单的实现qq侧滑菜单的样式。

        重点是学习功能强大的ViewDragHelper类,首先要初始化ViewDragHelper,它通常定义在ViewGroup的内部,并通过其静态工厂方法进行初始化。

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


第一个参数为要监听的view,第二个是一个callback回调。这个回调就是ViewDragHelper的逻辑核心,后面再来做详细讲解。

接下来要重写事件拦截方法,然后将事件传递给ViewDragHelper进行处理,这个操作必不可少,相当于把触摸事件交给ViewDragHelper了。

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

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


使用ViewDragHelper同样需要重写computescroll方法,因为它的内部也是通过scroller来实现平滑移动的,可以使用模版代码。

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


接下来就是处理回调接口的实现。

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) {
return left;
}

// 拖动结束后调用
@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
protected void onFinishInflate() {
super.onFinishInflate();
mMenuView = getChildAt(0);
mMainView = getChildAt(1);
}
如果需要根据view的宽度来处理滑动效果就可以根据这个

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = mMenuView.getMeasuredWidth();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: