Android Scroll实现弹性滑动 一 列表下拉弹性滑动
我这一次讲使用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实现弹性滑动 一 列表下拉弹性滑动相关推荐
- Android m 自定义下拉菜单,Android实现动画效果的自定义下拉菜单功能
我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...
- css实现列表下拉菜单_逐行:点击打开下拉列表和菜单的高级CSS技巧
css实现列表下拉菜单 by David Piepgrass 由David Piepgrass 逐行:点击打开下拉列表和菜单的高级CSS技巧 (Line-by-line: advanced CSS t ...
- 仿【咪咕动漫】列表下拉刷新上拉加载
一.概述 本篇续 厦门之旅 的第二篇.这期间找工作真的心态几多变化,刚开始兴致高昂,信心满满,面试了几家不错的公司,结果都是因为工资问题不了了之.后面的连面试机会都没有了,每天在狭小的租房里面吃了睡, ...
- 【Android归纳】基于XListView的下拉刷新、上拉加载更多的控件分析
目录 前言 功能介绍 总体设计 组成 类关系图 详细设计 XlistViewHeader原理分析 XListViewFooter原理分析 XListView原理分析 代码带注释下载 目录 前言 如果你 ...
- Android仿手机淘宝多级下拉菜单
我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单.具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示.我相信很多人都想开发一个跟它一样的功能 ...
- Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout
下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...
- miniui列表下拉允许编辑且保存_办公小技巧:请个好用的文本代码编辑器
作为经常处理多文本的教职员.编辑人员.程序员,若仅用记事本作为文本或代码编辑工具,会感到功能严重不足.改用免费的高级编辑器Text Editor Pro,便会大大提高文本和代码的处理效率. 1. 又快 ...
- android 文字fly动画,超好看的下拉刷新动画Android代码实现
最近看到了好多高端.大气.上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画. 首先我们看一下效果如何: 怎么样 ...
- 微信小程序实现循环列表下拉功能(点击事件)
在微信小程序里 有下拉功能 如果循环列表 当执行点击事件的时候就会同时执行.下面主要实现了循环列表的点击事件操作.(也有数据里面嵌套数据) wxml <view class="sele ...
- SharePoint列表下拉框优化
由于SharePoint列表的下拉框不能搜索, 客户使用体验非常不好,花了一天时间封装了JS代码,实际效果图如下 (在SharePoint列表上面自动生成文本框,类似百度形式搜索下拉框内容,选择之后下 ...
最新文章
- 简单分析beyond作曲
- 计算机学院杨洋,美国莱特州立大学吴志强教授访问计算机科学与技术学院
- .NET MongoDB Driver 2.2使用示例
- 独家专访 | 红布林(Plum​)庞博:万亿元二手时尚交易蓝海的生存法则
- zigbee ti 附带工具使用方法
- maven依赖循环引用_shiro+spring boot+mybatis启动循环引用问题解决思路和方案
- 使用Lightbox制作照片条
- 零垃圾创建数百万个对象
- BZOJ2286 : [Sdoi2011]消耗战
- linux的驱动开发——内核模块的编译
- 《python透明人士,他是凭什么成为主流编程的宠儿?!》Python 正则表达式
- java几种集合遍历速度对比
- SQL SERVER 2000数据库,转换为ACCESS数据库(已解决ACCESS自动编号问题)
- MatConvnet工具箱文档翻译理解五
- 安卓开发 监听系统语言切换
- 安全测试(五)Android APK软件安全 APP应用安全 手机软件安全 apk安全 apk反编译 应用日志窃取 apk漏洞 应用软件本身功能漏洞 高危权限泄密风险等 移动应用常规安全讲解
- iphone12android在线啥意思,iOS12要来了,你还不知道这些iPhone的隐藏功能?
- 在 Jupyter Notebook 中使用R语言
- 汽车OBD初级开发入门
- 【宝藏级构建桌面应用程序】使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序