Android Scroller 解读编写Demo

Scroller是一个专门用于处理滚动效果的工具类,大多数情况下,我们直接使用Scroller的场景并不多,但是很多大家所熟知的控件在内部都是使用Scroller来实现的,如ViewPager、ListView等。而如果能够把Scroller的用法熟练掌握的话,对于之后使用ViewPager更容易上手。

直接上源码,代码已经做了详细解读:

public class ScrollerLayout extends ViewGroup {

/*** 用于完成滚动操作的实例*/
private Scroller mScroller;
/*** 判定为拖动的最小移动像素数*/
private int mTouchSlop;
/*** 手机按下时的屏幕坐标*/
private float mXDown;
/*** 手机当时所处的屏幕坐标*/
private float mXMove;
/*** 上次触发ACTION_MOVE事件时的屏幕坐标*/
private float mXLastMove;
/*** 界面可滚动的左边界*/
private int leftBorder;
/*** 界面可滚动的右边界*/
private int rightBorder;public ScrollerLayout(Context context, AttributeSet attr) {super(context,attr);// 第一步,创建Scroller的实例mScroller=new Scroller(context);ViewConfiguration configuration=ViewConfiguration.get(context);//能够识别的最小滑动举例 ViewConfiguration.getScaledTouchSlop();//获取TouchSlop值mTouchSlop= configuration.getScaledTouchSlop();
}//定义View的位置在ViewGroup中的位置
//1)参数changed表示view有新的尺寸或位置;
//2)参数l表示相对于父view的Left位置;
//3)参数t表示相对于父view的Top位置;
//4)参数r表示相对于父view的Right位置;
//5)参数b表示相对于父view的Bottom位置。.
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {if(changed){int childCount=getChildCount();for (int i=0;i<childCount;i++){View childView=getChildAt(i);// 为ScrollerLayout中的每一个子控件在水平方向上进行布局//layout(a,b,c,d)中的四个参数是相对于父布局定义的//a和 b 是控件左边缘和上边缘相对于父类控件左边缘和上边缘的距离。// c 和 d是空间右边缘和下边缘相对于父类控件左边缘和上边缘的距离。childView.layout(i * childView.getMeasuredWidth(), 0, (i + 1) * childView.getMeasuredWidth(), childView.getMeasuredHeight());}// 初始化左右边界值leftBorder = getChildAt(0).getLeft();rightBorder = getChildAt(getChildCount() - 1).getRight();}}//View本身大小多少,由onMeasure()来决定
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//返回包含View的个数int childCount=getChildCount();for(int i=0;i<childCount;i++){//获取布局中的viewView childView=getChildAt(i);//规定了每个子view的尺寸,与当前的父View保持一致measureChild(childView,widthMeasureSpec,widthMeasureSpec);}
}@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()){//手指按下case MotionEvent.ACTION_DOWN://获取绝对坐标,相对于屏幕的X坐标mXDown = ev.getRawX();mXLastMove = mXDown;break;//手指滑动case MotionEvent.ACTION_MOVE:mXMove = ev.getRawX();float diff = Math.abs(mXMove - mXDown);mXLastMove = mXMove;// 当手指拖动值大于TouchSlop值时,认为应该进行滚动,拦截子控件的事件if (diff > mTouchSlop) {return true;}break;}return super.onInterceptTouchEvent(ev);
}@Override
public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_MOVE:mXMove=event.getRawX();int scrolledX=(int)(mXLastMove-mXMove);//getScrollX() 就是当前view的左上角相对于母视图的左上角的X轴偏移量if(getScrollX()+scrolledX<leftBorder){scrollTo(leftBorder, 0);return true;}else if(getScrollX() + getWidth()+scrolledX >rightBorder){scrollTo(rightBorder - getWidth(), 0);return true;}scrollBy(scrolledX, 0);mXLastMove = mXMove;//手指离开屏幕case MotionEvent.ACTION_UP:// 当手指抬起时,根据当前的滚动值来判定应该滚动到哪个子控件的界面int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();int dx = targetIndex * getWidth() - getScrollX();// 第二步,调用startScroll()方法来初始化滚动数据并刷新界面//invalidate()函数的主要作用是请求View树进行重绘// startScroll执行过程中即在duration时间内,// computeScrollOffset 方法会一直返回false,但当动画执行完成后会返回返加true.mScroller.startScroll(getScrollX(), 0, dx, 0);invalidate();break;}return super.onTouchEvent(event);
}
@Override
public void computeScroll() {// 第三步,重写computeScroll()方法,并在其内部完成平滑滚动的逻辑if (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());//invalidate()函数的主要作用是请求View树进行重绘invalidate();}
}

学习使用安卓scroller相关推荐

  1. 基于深度学习的安卓恶意应用检测----------android manfest.xml + run time opcode, use 深度置信网络(DBN)...

    基于深度学习的安卓恶意应用检测 from:http://www.xml-data.org/JSJYY/2017-6-1650.htm 苏志达, 祝跃飞, 刘龙     摘要: 针对传统安卓恶意程序检测 ...

  2. 学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?

    文章目录 1. 卷首语 2.中低配置(6000元价位) 2.1 系统配置 2.2 编译配置 2.3 编译时间 (约200分钟) build completed successfully (03:23: ...

  3. 安卓学习专栏——安卓报错Version 28 (intended for Android Pie and below) is the last version of the legacy suppor

    步骤 系列文章 前言 1.报错效果 2.修改方法 总结 系列文章 提示:转到安卓学习专栏,观看更多内容! 点我直达–>安卓学习专栏 前言 'com.android.support:appcomp ...

  4. 我的Android前生今世之缘-学习经验-安卓入门教程(六)

    关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号 欢迎大家关注我的微信公众号:「醉翁猫咪」 据我所知,网上教学资料一堆一堆的,那么还有很多人说,如何学习? ...

  5. 我的Android前生今世之缘-学习经验-安卓教程(六)

    点击上方    "醉翁猫咪"    ,选择    "置顶公众号" 有趣有内涵的文章第一时间送达! 喝酒I创作I分享 生活中总有些东西值得分享 @醉翁猫咪 据我所 ...

  6. 安卓学习专栏——安卓报错android.support.v4.widget.SwipeRefreshLayout飘红

    步骤 系列文章 1.报错效果 2.修改方法使用新的标签名 总结 系列文章 提示:转到安卓学习专栏,观看更多内容! 点我直达–>安卓学习专栏 1.报错效果 第一行代码酷欧天气实战时飘红 安卓报错a ...

  7. 安卓学习专栏——安卓报错android.support.v4.widget.DrawerLayout飘红

    步骤 系列文章 1.报错效果 2.修改方法使用新的标签名 总结 系列文章 提示:转到安卓学习专栏,观看更多内容! 点我直达–>安卓学习专栏 1.报错效果 第一行代码酷欧天气实战时飘红 安卓报错a ...

  8. 学习开发安卓应用总结(快速了解-从下载软件到开发运行APP)

    快速开发一个安卓应用 1.安装Andriod Studio,配置环境 2.运行调试APP 2.1 下载Genymotion模拟真机调试APP(视情况) 2.2 真机调试使用APP 2.3 运行他人项目 ...

  9. 哇塞!终于可以不用开会员了!安利一款英语学习神器安卓和iOS都可以使用!

    年轮单词 今天Aliwen给小伙伴们带来的是年轮单词APP,这神器简直太舒服了.同时支持安卓和苹果手机,真好!首先,大家在文章底部获取到关键词,然后下载,安装,注册自己的手机号即可! 内我们进来就可以 ...

最新文章

  1. [Webapp]国内移动端浏览器占比
  2. 为什么雷军指责“华为不懂研发”?
  3. 天猫精灵可以当电脑音响吗_阿里投百亿砸天猫精灵,马云的物联网野心能靠智能音箱撑起来吗?...
  4. 计算机制图的简称市什么,计算机地的图制图复习题.doc
  5. python编程正方形面积_编程里面的算法真的很难吗?
  6. python3安装cv2 安装opencv 2019发布
  7. 机械制图国家标准的绘图模板_JS制图:映射
  8. 语音特征:mfcc、fbank和语谱图概述
  9. 适当修改LIO-SAM_based_relocalization解决初始重定位显示错误
  10. AI产品经理-人工智能的发展
  11. html背景图片定位方法
  12. 漫画:设计模式六大原则(上)
  13. 文本纠错--CRASpell模型
  14. c语言表达式的算法,表达式求值--数据结构C语言算法实现
  15. Revit API之BoundingBoxXYZ的用法和剖面框(Section Box)
  16. win10安装MingW64
  17. 小学生台灯哪个品牌更护眼?精选教育部认可护眼灯品牌
  18. 【通信原理】实验五 基于Matlab的2ASK和2FSK调制解调
  19. LOL无限火力是哪个服务器先上线,LOL无限火力2019什么时间上线 2019LOL无限火力新玩法了解一下...
  20. queue与topic的区别

热门文章

  1. Gartner 公布 2022 新兴技术成熟度曲线,这些技术趋势最值得关注
  2. cpu.h-栈的宏定义-满减栈
  3. hiho 满减优惠(暴力)
  4. 失传千年AE特效真经(三)
  5. python打字测速_【pygame游戏编程】第四篇-----打字测速游戏
  6. 内网监控群晖918+(docker telegraf influxdb grafana)
  7. IPv4头部结构详解
  8. 《码农翻身》总结整理
  9. 去掉串口硬盘的安全删除硬件图标
  10. nmap扫描mysql弱口令_弱口令检测和端口扫描