我这一次讲使用scroll实现弹性滑动,我不会只有一个例子就说完,因为写文章的时候我也在学习,我分几次讲完吧。

首先上一段代码,

private void smoothScrollByScroller(int dy){mScroller.startScroll(0,dy,0,dy*-1,1000);invalidate();
}@Override
public void computeScroll() {if (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();}
}

这段代码是实现弹性滑动的核心,第一个函数指的是缓慢滑动的意思,但是却没有这个滑动的实际功能。
startScroll这函数的五个参数指的是起点x坐标,起点y坐标,x位移量,y位移量,这段滑动的时间。这个函数的内部是不断计算在滑动时间里x和y坐标应该是什么值,然后因为invalidate会调用computeScroll,这个computeScrollOffset函数是判断当前滑动是否结束,如果没有结束通过getCurrX和getCurry获得startScroll函数计算的值,在使用scrollTo滑动相应的位置,因为startScroll会运算很多次,也就是将滑动时间分成很多段,相应的坐标也都算出来,跟着给scrollTo去实现滑动。
这很像是ValueAmition,将时间分成很多段,然后计算相应的值,同时分很多次去实现。

我贴一个类似QQ消息列表的常见的弹性滑动,这里下拉是没有刷新的,

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}public final class PullView extends ViewGroup {private int mLastY;private Context mContext;private Scroller mScroller;//子View的个数private int mChildCount;public PullView(Context context){this(context,null);}public PullView(Context context, AttributeSet attributeSet){super(context,attributeSet);mContext=context;initView();}private void initView(){mScroller=new Scroller(mContext);}@Overridepublic boolean onTouchEvent(MotionEvent event) {int y=(int)event.getY();switch (event.getAction()){//手指按下时,初始化按下位置的X,Y位置值case MotionEvent.ACTION_DOWN:mLastY=y;break;//计算滑动的偏移量,产生滑动效果case MotionEvent.ACTION_MOVE://手指向下滑动delayY>0,向上滑动delayY<0int delayY=y-mLastY;delayY=delayY*-1;scrollBy(0,delayY);break;case MotionEvent.ACTION_UP:/*** scrollY是指:View的上边缘和View内容的上边缘(其实就是第一个ChildView的上边缘)的距离* scrollY=上边缘-View内容上边缘,scrollTo/By方法滑动的知识View的内容* 往下滑动scrollY是负值*/int scrollY=getScrollY();smoothScrollByScroller(scrollY);break;}mLastY=y;return true;}/*** 执行滑动效果* 使用scroller实现* @param dy*/private void smoothScrollByScroller(int dy){mScroller.startScroll(0,dy,0,dy*-1,1000);invalidate();}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();}}/*** 重新计算子View的高度和宽度* @param widthMeasureSpec* @param heightMeasureSpec*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int measuredWidth;int measureHeight;mChildCount = getChildCount();//测量子ViewmeasureChildren(widthMeasureSpec, heightMeasureSpec);int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);int widthSpaceMode = MeasureSpec.getMode(widthMeasureSpec);int heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec);int heightSpaceMode = MeasureSpec.getMode(heightMeasureSpec);//获取横向的padding值int paddingLeft=getPaddingLeft();int paddingRight=getPaddingRight();final View childView = getChildAt(0);/*** 如果子View的数量是0,就读取LayoutParams中数据* 否则就对子View进行测量* 此处主要是针对wrap_content这种模式进行处理,因为默认情况下* wrap_content等于match_parent*/if (mChildCount == 0) {ViewGroup.LayoutParams layoutParams=getLayoutParams();if(layoutParams!=null){setMeasuredDimension(layoutParams.width,layoutParams.height);}else {setMeasuredDimension(0, 0);}} else if (heightSpaceMode == MeasureSpec.AT_MOST && widthSpaceMode == MeasureSpec.AT_MOST) {measuredWidth = childView.getMeasuredWidth() * mChildCount;measureHeight = getChildMaxHeight();//将两侧的padding值加上去measuredWidth=paddingLeft+measuredWidth+paddingRight;setMeasuredDimension(measuredWidth, measureHeight);} else if (heightSpaceMode == MeasureSpec.AT_MOST) {measureHeight = getChildMaxHeight();setMeasuredDimension(widthSpaceSize, measureHeight);} else if (widthSpaceMode == MeasureSpec.AT_MOST) {measuredWidth = childView.getMeasuredWidth() * mChildCount;measuredWidth=paddingLeft+measuredWidth+paddingRight;setMeasuredDimension(measuredWidth, heightSpaceSize);}}/*** 获取子View中最大高度* @return*/private int getChildMaxHeight(){int maxHeight=0;for (int i = 0; i < mChildCount; i++) {View childView = getChildAt(i);if (childView.getVisibility() != View.GONE) {int height = childView.getMeasuredHeight();if(height>maxHeight){maxHeight=height;}}}return maxHeight;}/*** 设置子View的布局* @param changed* @param l* @param t* @param r* @param b*/@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int childLeft = 0;for (int i = 0; i < mChildCount; i++) {View childView = getChildAt(i);if (childView.getVisibility() != View.GONE) {int childWidth = childView.getMeasuredWidth();childView.layout(childLeft, 0, childLeft + childWidth, childView.getMeasuredHeight());childLeft += childWidth;}}}
}<android.com.listfragment.PullView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="1500dp"android:background="#806363"></LinearLayout>
</android.com.listfragment.PullView>

这里的ViewGroup的绘画和测量我就不多说,我就说一下它获取函数,计算坐标的一些事。

它在手指按下时记录y坐标,在手指移动时,跟着移动子View,在手指抬起时,使用弹性滑动的函数smoothScrollByScroller。
大家会发现为什么一些计算出的坐标要加负号,因为在我们人眼里,我们下拉y坐标的位移量是正的,但是在系统认为这个值是负的,原因我太菜不知道,知道的求大神评论留言告诉。

下一次写一个随手指弹性滑动的例子。

再见

Android Scroll实现弹性滑动 一 列表下拉弹性滑动相关推荐

  1. Android m 自定义下拉菜单,Android实现动画效果的自定义下拉菜单功能

    我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...

  2. css实现列表下拉菜单_逐行:点击打开下拉列表和菜单的高级CSS技巧

    css实现列表下拉菜单 by David Piepgrass 由David Piepgrass 逐行:点击打开下拉列表和菜单的高级CSS技巧 (Line-by-line: advanced CSS t ...

  3. 仿【咪咕动漫】列表下拉刷新上拉加载

    一.概述 本篇续 厦门之旅 的第二篇.这期间找工作真的心态几多变化,刚开始兴致高昂,信心满满,面试了几家不错的公司,结果都是因为工资问题不了了之.后面的连面试机会都没有了,每天在狭小的租房里面吃了睡, ...

  4. 【Android归纳】基于XListView的下拉刷新、上拉加载更多的控件分析

    目录 前言 功能介绍 总体设计 组成 类关系图 详细设计 XlistViewHeader原理分析 XListViewFooter原理分析 XListView原理分析 代码带注释下载 目录 前言 如果你 ...

  5. Android仿手机淘宝多级下拉菜单

    我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单.具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示.我相信很多人都想开发一个跟它一样的功能 ...

  6. Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout

    下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...

  7. miniui列表下拉允许编辑且保存_办公小技巧:请个好用的文本代码编辑器

    作为经常处理多文本的教职员.编辑人员.程序员,若仅用记事本作为文本或代码编辑工具,会感到功能严重不足.改用免费的高级编辑器Text Editor Pro,便会大大提高文本和代码的处理效率. 1. 又快 ...

  8. android 文字fly动画,超好看的下拉刷新动画Android代码实现

    最近看到了好多高端.大气.上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画. 首先我们看一下效果如何: 怎么样 ...

  9. 微信小程序实现循环列表下拉功能(点击事件)

    在微信小程序里 有下拉功能 如果循环列表 当执行点击事件的时候就会同时执行.下面主要实现了循环列表的点击事件操作.(也有数据里面嵌套数据) wxml <view class="sele ...

  10. SharePoint列表下拉框优化

    由于SharePoint列表的下拉框不能搜索, 客户使用体验非常不好,花了一天时间封装了JS代码,实际效果图如下 (在SharePoint列表上面自动生成文本框,类似百度形式搜索下拉框内容,选择之后下 ...

最新文章

  1. 简单分析beyond作曲
  2. 计算机学院杨洋,美国莱特州立大学吴志强教授访问计算机科学与技术学院
  3. .NET MongoDB Driver 2.2使用示例
  4. 独家专访 | 红布林(Plum​)庞博:万亿元二手时尚交易蓝海的生存法则
  5. zigbee ti 附带工具使用方法
  6. maven依赖循环引用_shiro+spring boot+mybatis启动循环引用问题解决思路和方案
  7. 使用Lightbox制作照片条
  8. 零垃圾创建数百万个对象
  9. BZOJ2286 : [Sdoi2011]消耗战
  10. linux的驱动开发——内核模块的编译
  11. 《python透明人士,他是凭什么成为主流编程的宠儿?!》Python 正则表达式
  12. java几种集合遍历速度对比
  13. SQL SERVER 2000数据库,转换为ACCESS数据库(已解决ACCESS自动编号问题)
  14. MatConvnet工具箱文档翻译理解五
  15. 安卓开发 监听系统语言切换
  16. 安全测试(五)Android APK软件安全 APP应用安全 手机软件安全 apk安全 apk反编译 应用日志窃取 apk漏洞 应用软件本身功能漏洞 高危权限泄密风险等 移动应用常规安全讲解
  17. iphone12android在线啥意思,iOS12要来了,你还不知道这些iPhone的隐藏功能?
  18. 在 Jupyter Notebook 中使用R语言
  19. 汽车OBD初级开发入门
  20. 【宝藏级构建桌面应用程序】使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序

热门文章

  1. 万字详解车路协同、C-V2X通信协议
  2. 智力游戏教案c语言代码,幼儿园智力游戏教案有哪些
  3. 2003服务器安全攻略
  4. 依图科技(北京)计算机视觉算法实习生面经-2020年10月
  5. HHUOJ 1895 果冻豆
  6. A Magic Lamp
  7. 30天自制C++服务器
  8. Reached heap limit Allocation failed - JavaScript heap out of memory
  9. 记录nginx获取的真实ip多了 的问题
  10. footer的设置绝不只是设置footer:使html高、宽自适应和footer始终在网页最末尾