Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动
16lz
2021-01-23
之前的分析与一种解决方案,当前例子未充分考虑处理Touch事件,之后会接着完善例子。
《Android 滑动侧边栏(Sliding Menu)实现分析》
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 1 手动滚动+自动滚动》 (本篇文章)
《Android 滑动侧边栏(Sliding Menu)第一种实现 - 2 手动滚动+自动滚动 + 事件处理》
《Android 滑动侧边栏(Sliding Menu)第二种实现方式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
更多相关文章
- Android图像开源视图:SmartImageView
- Android 利用Matrix实现图片随手指平移、旋转、缩放
- Android视图绘制流程完全解析,带你一步步深入了解View(二)
- Android自定义视图四:定制onMeasure强制显示为方形
- Android自定义视图三:给自定义视图添加“流畅”的动画
- android studio 3.6.0 绑定视图新特性
- UI组件之AdapterView及其子类(二)GridView网格视图的使用
- 界面编程之基本界面组件(7)ImageView(图像视图)