Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理
2013-03-19 17:33
393 查看
《Android 滑动侧边栏(Sliding Menu)实现分析》
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动》
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理》(本篇文章)
《Android 滑动侧边栏(Sliding Menu)第二种实现方式1》
一、 有图有真相
![](http://img.my.csdn.net/uploads/201303/13/1363104030_8181.gif)
二、分析与伪码
1. 添加onIntercepteEvent, 只有当手指在右侧视图上并且移动超过一定距离,满足这连个条件拦截交由ViewGoup执行滚动
[java] view
plaincopyprint?
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int actioin = ev.getAction();
final int x = (int) ev.getX();
switch (actioin) {
case MotionEvent.ACTION_DOWN:
mInterceptMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
final int deltaX = x - mInterceptMotionX;
final int distance = Math.abs(deltaX);
// 点击区域必须在右侧视图,因为仅右侧视图可移动
// 横向移动超过一定距离,可以自己根据需求改动
if ( canSliding(ev) && distance > mTouchSlop * 2) {
// 置为初始值
mLastX = x;
if (mScrollRunnable != null) {
mScrollRunnable.endScroll();
mScrollRunnable = null;
}
// 拦截Touch Event 交由当前ViewGruop onTouchEvent处理
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mInterceptMotionX = 0;
break;
}
return false;
}
2. 上面用到的判断是否是右侧视图改变canSliding方法内部实现改变,使用ViewGroup.dispatchTouchEvent中判断方式。
[java] view
plaincopyprint?
/**
* 当前手指点击位置是否在右侧视图区域内
*
* @param event
* @return true 可以滚动
*/
private boolean canSliding(MotionEvent event) {
final int scrolledXInt = (int) (event.getX() + getScrollX());
final int scrolledYInt = (int) (event.getY() + getScrollY());
Rect frame = new Rect();
mRightView.getHitRect(frame);
if (frame.contains(scrolledXInt, scrolledYInt)) {
return true;
}
return false;
}
3. 改变onTochEvent,ACTION_DOWN的处理放到onInterceptTouchEvent中了,而且ViewGroup也不需要拦截DOWN事件,所以DOWN事件从onTochEvent删除。
[java] view
plaincopyprint?
@Override
public boolean onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
scrollIfNeed(x);
return true;
case MotionEvent.ACTION_UP:
autoScrollIfNeed(x);
break;
}
return false;
}
4. scrollIfNeed方法改变,右侧视图盖住左侧视图时,隐藏左侧视图,目的是为了此时左侧视图不接收Touch Event
[java] view
plaincopyprint?
private void scrollIfNeed(final int x) {
// 计算与上次的偏移量
int deltaX = x - mLastX;
// 减少移动次数
if (x != mLastX) {
// 显示
if (mLeftView.getVisibility() != View.VISIBLE) {
mLeftView.setVisibility(View.VISIBLE);
}
int l = mRightView.getLeft();
int t = mRightView.getTop();
int b = mRightView.getBottom();
// 右侧视图的滑动区域,只能在左侧视图范围内滑动
int rightViewLeft = Math.max(mLeftView.getLeft(), l + deltaX);
rightViewLeft = Math.min(mLeftView.getRight(), rightViewLeft);
// 控制随手指滑动
mRightView.layout(rightViewLeft, t, rightViewLeft + mRightView.getWidth(), b);
}
// 滑动到最左侧
if (mRightView.getLeft() == mLeftView.getLeft()) {
mLeftView.setVisibility(View.INVISIBLE);
}
// 记录当前值供下次计算
mLastX = x;
}
三、完整源码下载
源码下载地址
原文地址:http://blog.csdn.net/love_world_/article/details/8666210
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动》
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理》(本篇文章)
《Android 滑动侧边栏(Sliding Menu)第二种实现方式1》
一、 有图有真相
![](http://img.my.csdn.net/uploads/201303/13/1363104030_8181.gif)
二、分析与伪码
1. 添加onIntercepteEvent, 只有当手指在右侧视图上并且移动超过一定距离,满足这连个条件拦截交由ViewGoup执行滚动
[java] view
plaincopyprint?
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int actioin = ev.getAction();
final int x = (int) ev.getX();
switch (actioin) {
case MotionEvent.ACTION_DOWN:
mInterceptMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
final int deltaX = x - mInterceptMotionX;
final int distance = Math.abs(deltaX);
// 点击区域必须在右侧视图,因为仅右侧视图可移动
// 横向移动超过一定距离,可以自己根据需求改动
if ( canSliding(ev) && distance > mTouchSlop * 2) {
// 置为初始值
mLastX = x;
if (mScrollRunnable != null) {
mScrollRunnable.endScroll();
mScrollRunnable = null;
}
// 拦截Touch Event 交由当前ViewGruop onTouchEvent处理
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mInterceptMotionX = 0;
break;
}
return false;
}
2. 上面用到的判断是否是右侧视图改变canSliding方法内部实现改变,使用ViewGroup.dispatchTouchEvent中判断方式。
[java] view
plaincopyprint?
/**
* 当前手指点击位置是否在右侧视图区域内
*
* @param event
* @return true 可以滚动
*/
private boolean canSliding(MotionEvent event) {
final int scrolledXInt = (int) (event.getX() + getScrollX());
final int scrolledYInt = (int) (event.getY() + getScrollY());
Rect frame = new Rect();
mRightView.getHitRect(frame);
if (frame.contains(scrolledXInt, scrolledYInt)) {
return true;
}
return false;
}
3. 改变onTochEvent,ACTION_DOWN的处理放到onInterceptTouchEvent中了,而且ViewGroup也不需要拦截DOWN事件,所以DOWN事件从onTochEvent删除。
[java] view
plaincopyprint?
@Override
public boolean onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
scrollIfNeed(x);
return true;
case MotionEvent.ACTION_UP:
autoScrollIfNeed(x);
break;
}
return false;
}
4. scrollIfNeed方法改变,右侧视图盖住左侧视图时,隐藏左侧视图,目的是为了此时左侧视图不接收Touch Event
[java] view
plaincopyprint?
private void scrollIfNeed(final int x) {
// 计算与上次的偏移量
int deltaX = x - mLastX;
// 减少移动次数
if (x != mLastX) {
// 显示
if (mLeftView.getVisibility() != View.VISIBLE) {
mLeftView.setVisibility(View.VISIBLE);
}
int l = mRightView.getLeft();
int t = mRightView.getTop();
int b = mRightView.getBottom();
// 右侧视图的滑动区域,只能在左侧视图范围内滑动
int rightViewLeft = Math.max(mLeftView.getLeft(), l + deltaX);
rightViewLeft = Math.min(mLeftView.getRight(), rightViewLeft);
// 控制随手指滑动
mRightView.layout(rightViewLeft, t, rightViewLeft + mRightView.getWidth(), b);
}
// 滑动到最左侧
if (mRightView.getLeft() == mLeftView.getLeft()) {
mLeftView.setVisibility(View.INVISIBLE);
}
// 记录当前值供下次计算
mLastX = x;
}
三、完整源码下载
源码下载地址
原文地址:http://blog.csdn.net/love_world_/article/details/8666210
相关文章推荐
- Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理
- Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动
- Android 轮播图的实现 自动+手动滑动+指示+点击事件
- Android自定义ViewGroup自动换行实现滑动任意布局及事件处理效果
- Android:实现手势滑动的事件处理方法
- Android面面观——Android事件处理下(按键、触摸屏和滚动球的一些实现细节)
- Android实现手势滑动的事件处理方法
- Android ViewPager实现无限循环(2.加入小圆点,优化自动和手动滑动冲突)
- [android]bunner的自动滚动和手动滑动
- Android 滑动侧边栏(Sliding Menu)第二种实现方式 1
- Android面面观——Android事件处理下(按键、触摸屏和滚动球的一些实现细节)
- android仿微信录制短视频,拍照,自动聚焦,手动聚焦,滑动缩放功能(Camera+TextureView+rxjava实现)
- Android:实现手势滑动的事件处理方法
- Android:实现手势滑动的事件处理方法
- Android:实现手势滑动的事件处理方法
- Android 使用Scroller自动滚动第一种实现
- Android:实现手势滑动的事件处理方法
- Android事件处理下(按键、触摸屏和滚动球的一些实现细节)
- Android事件处理(按键、触摸屏和滚动球的一些实现细节)
- Android:实现手势滑动的事件处理方法