View事件体系学习(一)滑动
来源:互联网 发布:知行供应链 编辑:程序博客网 时间:2024/05/21 17:13
一、View 的滑动可以通过三种方法来实现:
- 通过 View 本身提供的 scrollTo / scrollBy 方法来实现。
- 通过动画给 View 施加平移效果来实现滑动。
- 通过改变 View 的 LayoutParams 使得 View 重新布局从而实现滑动。
(一) scrollTo / scroll By
scrollTo:
scrollBy:
丛源码来看,scrollBy 调用了 scrollTo, 而最终 scrollTo 调用了 onScrollChanger() 方法。
在滑动过程中:
mScrollX 的值总是等于 View 左边缘和 View 内容左边缘在水平方向上的距离。
mScrollY 的值总是等于 View 上边缘和 View 内容上边缘在竖直方向上的距离。View 的边缘是指 View 的位置,由四个顶点组成,
而View内容的边缘是指 View 中的内容的边缘。scrollTo / scrollBy 只能改变 View 内容的位置而不能改变 View 在布局中的位置。
mScrollX 和 mScrollY 的单位为像素,并且当 View 左边缘在 View 内容左边缘的右边时,mScrollX 为正值,反之为负值;当 View 的上边缘在 View 内容的上边缘的下边时, mScrollY 为正值,反之为负值。
从左向右化滑动,那么 mScrollX 为负值,反之为正值。 从上往下滑动,哪么 mScrollY 为负值,反之为正值。
(二)使用动画
使用动画来移动 View,主要是操作 View 的 translationX 和 translationY 属性,既可以采用传统的 View 动画,也可以采用属性动画,如果采用属性动画的话,需要注意兼容 3.0 以下的版本。
(三)改变布局参数
通过 view.getLayoutParams() 方法获得LayoutParams 对象,在该对象中,通过修改margin、width等属性来实现 View 的滑动效果。
总结:
scrollTo / scrollBy: 操作简单,适合对 view 内容的滑动。
但是它只能滑动 view 的内容,不能滑动 view 的本身。动画:操作简单,主要适用于没有交互的 View 和实现复杂的动画效果。
如果使用属性动画,哪么采用这种方式没有明显的缺点。改变布局参数:操作稍微复杂,适用于有交互的 View。
二、弹性滑动的实现:
(一)使用Scroller
先看代码:
private Scroller scroller = new Scroller(getContext()); public void smoothScroollTo(int destX,int dextY,int duration){ int scrollX = getScrollX(); int deltaX = destX - scrollX; int scrollY = getScrollY(); int deltaY = dextY - scrollY; scroller.startScroll(scrollX,scrollY,deltaX,deltaY,duration); invalidate(); } @Override public void computeScroll() { if (scroller.computeScrollOffset()){ scrollTo(scroller.getCurrX(),scroller.getCurrY()); postInvalidate(); } }
有几个注意的地方:
1,必须重写 View 的 computeScroll() 方法。
2,scroller.startScroll()其实并没有使 View 进行滑动,而是保存了我们传递的几个参数:
public void startScroll(int startX, int startY, int dx, int dy, int duration) { mMode = SCROLL_MODE; mFinished = false; mDuration = duration; mStartTime = AnimationUtils.currentAnimationTimeMillis(); mStartX = startX; mStartY = startY; mFinalX = startX + dx; mFinalY = startY + dy; mDeltaX = dx; mDeltaY = dy; mDurationReciprocal = 1.0f / (float) mDuration; }
在保存好参数之后,我们需要调用 invalidate() 方法让 View 重绘,而在 View 重绘的 draw() 方法又会去调用 computeScroll 方法。
3,computeScrollOffset:
public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX mCurrX = Math.min(mCurrX, mMaxX); mCurrX = Math.max(mCurrX, mMinX); mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); // Pin to mMinY <= mCurrY <= mMaxY mCurrY = Math.min(mCurrY, mMaxY); mCurrY = Math.max(mCurrY, mMinY); if (mCurrX == mFinalX && mCurrY == mFinalY) { mFinished = true; } break; } } else { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } return true; }
该方法根据时间的流逝来计算出当前的 scrollX 和 scrollY 的值,返回 true 表示滑动未结束。
4, 使用 scroller 只能使内容进行滑动。
(二)通过动画
属性动画可以设置duration以及插值器来实现。
ObjectAnimator animator = ObjectAnimator.ofFloat(myScrollView, "translationX", 0f, 360f); animator.setDuration(3000); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.start();
具体的动画学习放在以后=。=
(三)使用延时策略
使用延时策略的核心思想是,通过发送一系列延时消息从而达到一种渐进式的效果,具体来说可以使用 Handler 或 View 的 postDelayed 方法,也可以使用线程的 sleep 方法。
- View事件体系学习(一)滑动
- 学习笔记:View的事件体系2:View的滑动
- 学习笔记:View的事件体系3:弹性滑动
- View事件体系之--View的滑动
- View 的事件体系---View的滑动
- View事件体系-View的滑动
- View的事件体系(一)——View的基础知识以及View的滑动
- Android——View的事件体系(一)View的滑动
- View的事件体系(上)(View基础知识,滑动,弹性滑动)
- View的事件体系(一)
- View的事件体系---V3.2 View的滑动
- View事件体系(二)View的滑动
- View的事件体系之--View的弹性滑动Scroller
- View事件体系之View的的滑动
- 《View的事件体系》(二)View的滑动实现
- View的事件体系(下)(事件分发,滑动冲突)
- Android读书笔记-------View的事件体系 一
- 读书笔记--View的事件体系(一)
- spring中ContextLoaderListener和DispatcherServlet区别
- eclipse maven插件方式启动项目
- PHP邮件mail()函数解析和SMTP使用方法及乱码问题
- Eclipse工具Debug详解
- python---学习笔记之序列化反序列化以及pickle模块
- View事件体系学习(一)滑动
- CodeForces 888D Almost Identity Permutations
- 【亲测】centos 7下编译并安装warp-ctc
- 数据结构与算法python版(二)--双向链表
- 【Scikit-Learn 中文文档】内核岭回归
- 配置apache cxf 客户端支持https
- 微信小程序:获取用户权限
- 指针运算、二级指针
- 循环结构的程序设计