记录使用Scroller实现平滑滚动,效果图如下:

一、自定义View中实现View的平滑滚动

public class ScrollerView extends View {private Scroller mScroller;private Paint mPaint;/*** 屏幕拖动最小像素*/private int mTouchSlop;/*** View宽度*/private int width;/*** View高度*/private int height;/*** MotionEvent.getX()*/private int mEventX;/*** MotionEvent.getY()*/private int mEventY;private Bitmap mBitmap;/*** View到屏幕左边距离*/private int mStartX;/*** View到屏幕顶部距离*/private int mStartY;/*** View默认大小*/private static int DEFAULT_SIZE = 200;public ScrollerView(Context context) {this(context, null);}public ScrollerView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);mPaint = new Paint();mScroller = new Scroller(context);ViewConfiguration configuration = ViewConfiguration.get(context);mTouchSlop = ViewConfigurationCompat.getScaledHoverSlop(configuration);mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);if (widthMode == MeasureSpec.EXACTLY) {width = MeasureSpec.getSize(widthMeasureSpec);} else {if (heightMode == MeasureSpec.EXACTLY) {width = MeasureSpec.getSize(heightMeasureSpec);} else {width = DEFAULT_SIZE;}}if (heightMode == MeasureSpec.EXACTLY) {height = MeasureSpec.getSize(heightMeasureSpec);} else {height = width;}setMeasuredDimension(width, height);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (null != mBitmap) {Rect src = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());Rect dst = new Rect(0, 0, width, height);canvas.drawBitmap(mBitmap, src, dst, mPaint);} else {Log.e("zzy", "Bitmap is null");}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:mEventX = (int) event.getX();mEventY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:mStartX = (int) event.getRawX() - mEventX;mStartY = (int) event.getRawY() - mEventY;layout(mStartX,mStartY,mStartX+width,mStartY+height);break;case MotionEvent.ACTION_UP:startScroller();break;}return true;}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()){int l = mScroller.getCurrX();layout(l,mStartY,l+width,mStartY+height);invalidate();}}/*** 开始Scroller动画*/private void startScroller(){mScroller.forceFinished(true);mScroller.startScroll(mStartX, mStartY,-mStartX,0);int screenWidth = getScreenWidth();// Scroller动画默认250ms,超过屏幕一半时设置为500msif (mStartX > screenWidth / 2){mScroller.extendDuration(500);}invalidate();}private int getScreenWidth(){return getResources().getDisplayMetrics().widthPixels;}
}

Scroller其实是个辅助类,本身并不能完成动画的执行。而是帮我们计算随着时间的流逝,动画应该执行的位置值,我们需要获得当前时间的位置,然后调用View位置移动方法,将View移动到该位置,完成动画。

所以,在自定义View中。我们需要调用invalidate()触发View的重绘,并覆写重绘会执行的方法computeScroll()

computeScroll()方法中调用ScrollercomputeScrollOffset()计算当前时间动画应该移动的位置,返回值是动画是否在执行。

通过mScroller.getCurrX()mScroller.getCurrY()获得当前时间的位置。手动调用View位置移动的方法将View的位置移动到当前时间的位置,实现View的滚动。

然后再次调用invalidate()触发刷新。直到computeScrollOffset()返回false,动画执行完成,滚动完成。

二、直接使用Scroller实现View的平滑滚动

我们知道,Scroller会帮我们计算当前时间,插值器返回的值。

而如果直接使用Scroller实现平滑滚动的话,也需要借助带时间的监听器。

这里借助ValueAnimator来实现Scroller平滑滚动

    private Scroller mScroller;private ImageView mImage;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mImage = findViewById(R.id.image);mScroller =new Scroller(this);}public void btnStart(View view){start();}private void start(){mScroller.forceFinished(false);mScroller.extendDuration(500);mScroller.startScroll(0,0,400,400);ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1);valueAnimator.setDuration(500);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {if (mScroller.computeScrollOffset()){ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mImage.getLayoutParams();params.leftMargin = mScroller.getCurrX();params.topMargin = mScroller.getCurrY();mImage.setLayoutParams(params);}}});valueAnimator.start();}

在ValueAnimator的addUpdateListener中刷新Scroller当前值。并移动位置。效果如下:

Android 使用 Scroller 实现平滑滚动相关推荐

  1. android scroller,深入理解Android中Scroller的滚动原理

    View的平滑滚动效果 什么是实现View的平滑滚动效果呢,举个简单的例子,一个View从在我们指定的时间内从一个位置滚动到另外一个位置,我们利用Scroller类可以实现匀速滚动,可以先加速后减速, ...

  2. android动手写平滑滚动歌词控件

    马上毕业了,前段时间一直忙自己的毕业设计和毕业论文,做的是一个android音乐播放器,今天特意抽出里面的一块功能来凑这篇博客--歌词的显示. 看看QQ音乐,歌词显示略屌,可惜我们的LRC文件并不能做 ...

  3. Android 游戏开发之主角的移动与地图的平滑滚动(十五)

    雨松MOMO带你走进游戏开发的世界之主角的移动与地图的平滑滚动 雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong. ...

  4. Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199) 我在上一篇文章中Android 带你从源码的角度解析 ...

  5. Android的Scroller介绍

    以提供的起始点和将要滑动的距离开始滚动.滚动会使用缺省值250ms作为持续时间. 参数 startX 水平方向滚动的偏移值,以像素为单位.负值表明滚动将向左滚动 startY 垂直方向滚动的偏移值,以 ...

  6. [原] Android中Scroller类的分析

    今天看了一下项目中用到的ViewFlow控件,想弄明白其工作原理.从头开始分析,卡在"滚动"这儿了. 做android也快两年了,连最基本的滚动都不熟悉,真是惭愧...遂网上找资料 ...

  7. 包含锚点平滑滚动效果/解决锚点链接碰到固定定位问题/导航选中背景变色/固顶/返回顶部效果全...

    <script type="text/javascript">$(function() {//锚点平滑滚动效果 $('a[href*=#],area[href*=#]' ...

  8. Android ListView 自定义背景后 滚动时的背景变黑问题

    ListView是常用的显示控件,默认背景是和系统窗口一样的透明色,如果给ListView加上背景图片,或者背景颜色时,滚动时listView会黑掉,原因是,滚动时,列表里面的view重绘时,用的依旧 ...

  9. 在WPF中实现平滑滚动

    原文:在WPF中实现平滑滚动 WPF实现滚动条还是比较方便的,只要在控件外围加上ScrollViewer即可,但美中不足的是:滚动的时候没有动画效果.在滚动的时候添加过渡动画能给我们的软件增色不少,例 ...

最新文章

  1. 马腾宇的AI学术历程:做科研要考虑长期的影响力
  2. 2019年中国科创板全面解读报告
  3. 工作组环境下WPAD部署的另类解决--WINS解析
  4. 全麦吐司和普通吐司的区别_全麦面包和普通面包的区别
  5. 编程之美----不要被阶乘吓到
  6. JAVA_IO流四大家族(1)
  7. 事务管理基础:排它锁和共享锁相关知识笔记
  8. 【python】1. 两数之和
  9. 1108. Finding Average (20)-PAT甲级真题
  10. mpvue 初始化微信小程序
  11. html table 向上滚动,决策报表的表格自动向上滚动问题
  12. Python学习笔记—Dict和set
  13. python制作一个简易计算器_最简易的python计算器实现源代码
  14. android subclipse subversive
  15. 如何用3D Max进行三维建模
  16. Python读写excel练习_去除excel中乱码行,并添加列
  17. win7旗舰版系统下载
  18. web开发视频教程,CSS颜色基本样式
  19. 【毕业设计】大数据疫情数据分析及可视化系统 - python
  20. 设置表头QHeaderView

热门文章

  1. 激活Windows Server 2003 2008终端授权服务器
  2. 青春散场,初心不忘【致毕业季理想主义的你】
  3. 【Visual C 】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术 Direct3D渲染五步曲
  4. idea查看类层级hierarchy快捷键
  5. 计算机应用基础的重点知识,《计算机应用基础知识》重点总结
  6. 喝酒骑行电瓶车属于违法或者犯罪吗?
  7. 云中和花木_王者荣耀:体验服英雄重大调整,云中君成野王,妲己射程加强,花木兰重回巅峰...
  8. 当极客 (Geek) 遇到呆瓜 (Nerd)
  9. atlsd.lib 和 atls.lib冲突
  10. MySQL轻快入门2021.3.18(事务)