版权说明 :《Android回弹阻尼效果的简单实现,非基于ListView,ScrollView于当前CSDN博客乘月网属同一原创,转载请说明出处,谢谢。


ReboundEffects

好久没有写Android博客了,这段时间有点浮躁,静不下心来写。趁今天周五心情好点,写个简单点的技术实现。

先简单说说回弹阻尼效果的思路,先自定义一个ViewGroup ----- ReboundEffectsView,通过手势的上下滑动距离差不断改变其子View(一般都是子ViewGroup)的相对于该ReboundEffectsView的位置(坐标),当手势为释放(action_up)或取消(action_cancel)时,重置子View最初始相对ReboundEffectsView的位置,最初始的位置值应在处理滑动事件前保存下来以用来重置。

Demo项目下载地址:https://github.com/ausboyue/ReboundEffects

进入代码板块

1.在自定义ReboundEffectsView中重写onFinishInflate方法,XML布局完成加载后获取其第一个子View(使用该ReboundEffectsView时应保证其只有且只有一个子View,唯一的独生子,我就叫它太子View):

/** * XML布局完成加载 */@Overrideprotected void onFinishInflate() {super.onFinishInflate();if (getChildCount() > 0) {mPrinceView = getChildAt(0);// 获得子View,太子View}}

2.onTouchEvent方法,分别对ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL事件进行处理:

/** * Touch事件 */@Overridepublic boolean onTouchEvent(MotionEvent e) {if (null != mPrinceView) {switch (e.getAction()) {case MotionEvent.ACTION_DOWN:onActionDown(e);break;case MotionEvent.ACTION_MOVE:return onActionMove(e);case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:onActionUp(e);// 当ACTION_UP一样处理break;}}return super.onTouchEvent(e);}

3.onActionDown中保存子View的初始上下高度位置:

/** * 手指按下事件 */private void onActionDown(MotionEvent e) {mVariableY = e.getY();/** * 保存mPrinceView的初始上下高度位置 */mInitTop = mPrinceView.getTop();mInitBottom = mPrinceView.getBottom();}

4.核心代码,onActionMove中,主要是判断手势移动事件是否为上下滑动事件,是的话根据上下滑动的绝对距离重绘子View的位置(这里的绝对距离除以2了,目的是放缓子View的移动速度),并在以后的Touch拿到直接的控制权,返回true:

/** * 手指滑动事件 */private boolean onActionMove(MotionEvent e) {float nowY = e.getY();float diff = (nowY - mVariableY) / 2;if (Math.abs(diff) > 0) {// 上下滑动// 移动太子View的上下位置mPrinceView.layout(mPrinceView.getLeft(), mPrinceView.getTop() + (int) diff, mPrinceView.getRight(),mPrinceView.getBottom() + (int) diff);mVariableY = nowY;isEndwiseSlide = true;return true;// 消费touch事件}return super.onTouchEvent(e);}

5.手指释放或手势取消时,则调用onActionUp方法恢复子View的位置:

/** * 手指释放事件 */private void onActionUp(MotionEvent e) {if (isEndwiseSlide) {// 是否为纵向滑动事件// 是纵向滑动事件,需要给太子View重置位置resetPrinceView();isEndwiseSlide = false;}}/** * 回弹,重置太子View初始的位置 */private void resetPrinceView() {TranslateAnimation ta = new TranslateAnimation(0, 0, mPrinceView.getTop() - mInitTop, 0);ta.setDuration(600);mPrinceView.startAnimation(ta);mPrinceView.layout(mPrinceView.getLeft(), mInitTop, mPrinceView.getRight(), mInitBottom);}

OK,整个自定义View中重写原生的方法并不多,也不需要自行测量和绘制View,代码逻辑也足够精简,如果有什么bug或建议可以在下面评论,我会继续更新博客。


更多相关文章

  1. Android中WebView点击事件的拦截跳转到原生的界面
  2. Android(安卓)View的事件分发机制探索
  3. android定制化软件修改或添加按键驱动的核心操作步骤讲解
  4. Android—— 4.2 Vold挂载管理_Kernel_USB_Uevent (七)
  5. Android事件机制(三)
  6. Android开发_精准排布控件位置
  7. Android(安卓)Monkey 压力测试 介绍
  8. ImageView的属性 android:scaleType
  9. android Toast显示消息的几种方法

随机推荐

  1. Android 开发中常用到的设计模式
  2. android竖向进度条简单实现
  3. Android超精准计步器开发-Dylan计步
  4. (收集)ListView中常用属性
  5. Android的数据存储形式
  6. Android下ContentProvider 学习总结
  7. Android--进度条--ProgressBar--SeekBar
  8. Android声纹识别程序
  9. [Android(安卓)开源项目学习]Android的UI
  10. android名词解释