之前的分析与一种解决方案,当前例子未充分考虑处理Touch事件,之后会接着完善例子。

《Android 滑动侧边栏(Sliding Menu)实现分析》

《Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动》 (本篇文章)

《Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理》

《Android 滑动侧边栏(Sliding Menu)第二种实现方式1》



一、 先来看看效果图

Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动_第1张图片



二、实现展示


方案 具体使用 可参考之前Demo
布局 ViewGroup(左测绿色视图和右侧蓝色视图分别是其子View) 《自定义ViewGrup》
手动滚动 ViewGroup.layout(left, top, right, bottom); 《layout方法官方文档》
自动滚动 Scroller 和 ViewGroup.layout(); 《Scroller Demo》


三、伪代码

1. 布局上面的Demo中可以找到相关Demo

2 手动滚动和自动滚动都是在onTouchEvent中进行控制,先看下源码,不喜欢贴大段的完整代码,最后会提供完整代码下载

public class SlidingMenus extends ViewGroup {private View mRightView;private View mLeftView;// 记录一次移动位置,用于计算移动偏移量private int mLastX;// 按下时记录,用于判断当前滚动时向左还是向右private int mMotionX;......@Overridepublic boolean onTouchEvent(MotionEvent event) {final int x = (int) event.getX();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mLastX = x;mMotionX = x;boolean inRegion = canSliding(event);return inRegion;case MotionEvent.ACTION_MOVE:scrollIfNeed(x);return true;case MotionEvent.ACTION_UP:autoScrollIfNeed(x);break;}return true;}......}


3.canSliding进行判断,仅右侧视图可以滚动,左侧视图不能滚动

/** * 只有右侧视图可以移动 *  * @param event * @return true 可以滚动 */private boolean canSliding(MotionEvent event) {int[] location = new int[2];// 获取右侧视图相对于屏幕坐标值mRightView.getLocationOnScreen(location);RectF region = new RectF();region.set(location[0] , location[1] ,location[0] + mRightView.getWidth(),location[1] + mRightView.getHeight());// 当前手指点击位置是否在右侧视图区域内boolean inRegion = region.contains(event.getRawX(), event.getRawY());return inRegion;}



4. 右侧视图随手指移动,具体实现方法在scrollIfNeed

private void scrollIfNeed(final int x) {// 计算与上次的偏移量int deltaX = x - mLastX;// 减少移动次数if (x != mLastX) {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);}// 记录当前值供下次计算mLastX = x;}

5. 手指抬起后,视图随手指自动滚动具体实现在autoScrollIfNeed

private void autoScrollIfNeed(final int x) {mScrollRunnable = new ScrollRunnable();// 用于判断滑动方向final int deltaX = x - mMotionX;// x轴向右是依次递增与手指落下点差值,小于0说明是手指向左滑动boolean moveLeft = deltaX <= 0;// 滑动距离超过左侧视图一半,才会沿着手指方向滚动final int distance = Math.abs(deltaX);if (distance < mLeftView.getWidth() / 2) {// 从哪来回哪去moveLeft = !moveLeft;}// 启动自动滚动mScrollRunnable.startScroll(moveLeft);}private class ScrollRunnable implements Runnable {// 滚动辅助类,提供起始位置,移动偏移,移动总时间,可以获取每次滚动距离private Scroller mScroller = new Scroller(getContext());@Overridepublic void run() {final Scroller scroller = mScroller;// 计算滚动偏移,返回是否可以接着滚动boolean more = scroller.computeScrollOffset();// 计算后获取需要滚动到的位置final int x = scroller.getCurrX();if (more) {// 与手动滚动调用的方法相同scrollIfNeed(x);// 当前子线程已经执行完,但是需要接着滚动// 所以把当前Runnable再次添加到消息队列中post(this);} else {// 不需要滚动endScroll();}}private void startScroll(boolean moveLeft) {// 滚动前设置初始值mLastX = mRightView.getLeft();int dx = 0;// 计算移动总距离if (moveLeft) {// 当前到左视图左侧边界距离dx = mLeftView.getLeft() - mRightView.getLeft();} else {// 到右侧边界dx = mLeftView.getRight() - mRightView.getLeft();}// 开始滚动mScroller.startScroll(mRightView.getLeft(), 0, dx, 0, 300);// 把当前Runnable添加到消息队列中post(this);}private void endScroll() {// 从消息队列中把当前Runnable删除,即停止滚动removeCallbacks(this);}}





四、完整源码下载

源码下载连接



原文地址:http://blog.csdn.net/love_world_/article/details/8657125







更多相关文章

  1. Android图像开源视图:SmartImageView
  2. Android 利用Matrix实现图片随手指平移、旋转、缩放
  3. Android视图绘制流程完全解析,带你一步步深入了解View(二)
  4. Android自定义视图四:定制onMeasure强制显示为方形
  5. Android自定义视图三:给自定义视图添加“流畅”的动画
  6. android studio 3.6.0 绑定视图新特性
  7. UI组件之AdapterView及其子类(二)GridView网格视图的使用
  8. 界面编程之基本界面组件(7)ImageView(图像视图)

随机推荐

  1. 为什么MySQL 删除表数据 磁盘空间还一直
  2. mysql中int(3)和int(10)的数值范围是否相
  3. 深入解析MySQL索引数据结构
  4. MySQL数据库必备之条件查询语句
  5. MySQL实例精讲单行函数以及字符数学日期
  6. MySQL数据库超时设置配置的方法实例
  7. Error generating final archive
  8. Android(安卓)是否前台运行
  9. android之显示Log
  10. Android(安卓)Retrofit 2.0框架上传图片,