高仿IOS下拉刷新的粘虫效果
最近看需要做一款下拉刷新的效果,由于需要和Ios界面保持一致,所以这用安卓的方式实现了ios下的下拉刷新的粘虫效果。
最新的安卓手机版本的QQ也有这种类似的效果,就是拖动未读信息的那个红色圆圈,拖动近距离的是就有这种粘虫的效果。
下面是安卓版本的嘟嘟App的效果截图,后面会简单的介绍下的实现原理
原理:
如下图所示,在没有进行下拉的是,显示的是A图,实际上是一个圆形,当进行向下的拖动的时候,圆形会进行拉伸,这里简单用模拟下圆形被用力拉伸的效果。
1、被拉伸的圆形,实际上分为3部分,上面的部分(是个半圆,稍微大点,简称为大圆),中间部分(是一个拉伸的部分,有2条平滑的曲线),下面部分(也是一个半圆,较小,成为小圆)
2、当滑动的距离越来越大的时候,模拟的力就越大,那么圆就拉伸越厉害。这样我们可以把上面的大圆和下面的小圆变的越来越小。中间部分,变成的越来越长。
3、拖动过程理解,那么简述下绘制的流程,从1点开始绘制,1~2是一个四分之一的圆形,2~3是一个曲线,我们可以用贝塞尔曲线来绘制,具体贝塞尔是什么东西,可以自行百度,这里不做解释。3~4是一个半圆,4~5和2~3一样,也是一个贝塞尔曲线。5~1和1~2一样也是四分之一的圆形。
上面就是简单原理,可能实际效果还是需要优化的,不过原理再次,后面只需要慢慢优化即可,当初实现这个功能也是费了2天时间。
下面是代码片段,具体完整代码,后面会给出下载链接。
public class RefreshView extends View {static final int BEZIER_OFFSET = McDimenUtil.dp2Px(15);// 贝塞尔曲线的偏移值static final int R = McDimenUtil.dp2Px(30); // 圆球的半径static final int Y_OFFSET = McDimenUtil.dp2Px(60); // 竖直方向最大的偏移值int currentX;int currentY;private boolean isReFreshed;private int offsetY;private OnPullRefreshCallback onPullRefreshCallback;private Paint paint;private Path path;int startX;int startY;public RefreshView(Context paramContext) {super(paramContext);init();}public RefreshView(Context paramContext, AttributeSet paramAttributeSet) {super(paramContext, paramAttributeSet);init();}public RefreshView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {super(paramContext, paramAttributeSet, paramInt);init();}static void addBcr(Path paramPath, int x1, int y1, int x2, int y2, float rate) {int i = (int) (rate * BEZIER_OFFSET);int cx = (x2 + x1) / 2 - i; // 控制点xsint cy = (y2 + y1) / 2 - i; // 控制点yparamPath.quadTo(cx, cy, x2, y2);}static void addBcr2(Path paramPath, int x1, int y1, int x2, int y2, float rate) {int i = (int) (rate * BEZIER_OFFSET);int cx = (x2 + x1) / 2 + i; // 控制点xsint cy = (y2 + y1) / 2 - i; // 控制点yparamPath.quadTo(cx, cy, x2, y2);}public void draw(Canvas paramCanvas) {super.draw(paramCanvas);update(paramCanvas);}void init() {this.path = new Path();this.paint = new Paint();this.paint.setAntiAlias(true);this.paint.setColor(Color.parseColor("#2baaff"));}public boolean onTouchEvent(MotionEvent event) {currentX = (int) event.getX();currentY = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startX = currentX;startY = currentY;break;case MotionEvent.ACTION_MOVE:// 计算偏移值,然后重新绘制setOffsetY(currentY - startY);break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:// 重置界面setOffsetY(0);startX = startY = currentY = currentX = 0;break;}return true; // super.onTouchEvent(event);}public boolean isReFreshed() {return this.isReFreshed;}public void setOffsetY(int offset) {this.offsetY = offset;if (offsetY >= 0) {invalidate();}}void update(Canvas paramCanvas) {this.path.reset();int width = getWidth();int height = getHeight();float rate = 1.0F * this.offsetY / height;int r = (int) (R * (1.0F - rate)); // 圆球的半径,动态改变的,当拖拉的时候,r的会根据距离改变,进行变化this.path.moveTo(width / 2, 0.0F);// 移动到(width/2 , 0)这个点this.path.arcTo(new RectF(width / 2 - r, 0.0F, r + width / 2, r * 2), -90.0F, 90.0F);// 根据半径r,换出一个四分之一的圆形int m = (int) (9.0F * (rate * r));// 算出底部的校园与上面的大圆的圆心的距离if ((m > Y_OFFSET) && (this.onPullRefreshCallback != null)) { // 如果这个距离超过了限制,则可以出发回调this.onPullRefreshCallback.onCallback();this.isReFreshed = true;invalidate();// return;}this.isReFreshed = false;int x2 = (int) (r + width / 2 - rate * r); // 小圆的水平的直径右边的点x坐标int y = r + m; // 小圆的圆心坐标,y坐标int x1 = (int) (width / 2 - r + rate * r);// 小圆的水平的直径左边的点x坐标// 绘制一个贝塞尔曲线addBcr(this.path, r + width / 2, r, x2, y, rate);int r2 = (x2 - x1) / 2; // 小圆的半径// 绘制一个半圆this.path.arcTo(new RectF(x1, y - r2, x2, y + r2), 0.0F, 180.0F);// 绘制一个贝塞尔曲线addBcr2(this.path, x1, y, width / 2 - r, r, rate);// 在绘制上面的一个四分之一园this.path.arcTo(new RectF(width / 2 - r, 0.0F, r + width / 2, r * 2), 180.0F, 90.0F);this.path.setFillType(Path.FillType.WINDING);paramCanvas.drawPath(this.path, this.paint);}public void setOnPullRefreshCallback(OnPullRefreshCallback callback) {this.onPullRefreshCallback = callback;}public static abstract interface OnPullRefreshCallback {public abstract void onCallback();}
}
运行效果:
完整代码下载地址:
地址
http://download.csdn.net/detail/xia215266092/8107081
高仿IOS下拉刷新的粘虫效果相关推荐
- Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout
下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...
- android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能,高仿京东下拉刷新,轻松上手!...
直接进入主题,先来看一下京东的实现效果: jd.gif 以及我自己的实现效果: myjd.gif 实现过程 1.下拉原理 layout.png 整个布局为继承自LinearLayout的Viewgro ...
- 仿美团下拉刷新控件(一)
如果想学习更多进阶知识,可以关注我的微信公众号:Android小菜. 也可以直接扫描二维码关注: 转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很有幸能进入美团.本文就仿写一下美团 ...
- 仿Ios下拉菜单,android Spinner效果(美团下拉效果)
先上效果图: 直接上代码: Ios spinner文件 package com.choe.iosspinner;import android.app.Activity; import android. ...
- 仿美团下拉刷新控件(二)
如果想学习更多进阶知识,可以关注我的微信公众号:Android小菜. 也可以直接扫描二维码关注: 转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 本篇是实现仿美团下拉刷新控件的第二篇 ...
- 微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果
微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果 一: 使用 wx.redirectTo(),实现页面刷新数据效果 API说明: 关闭当前页面,跳转到应 ...
- Android自定义控件之仿美团下拉刷新
android美团下拉刷新控件自定义控件 目录(?)[+] 美团的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull to refresh),在这个状态下是一个绿色的椭圆随着下拉的距离动 ...
- android组件的下拉回弹,Android自定义控件仿ios下拉回弹效果
网上有很多类似的文章,大多数还是继承listview来实现(主要是listview.addHeaderView()和listview.addFooterView在listview的首尾添加view,也 ...
- 自定义下拉刷新之仿AcFun下拉刷新
俗话说好记性不如烂笔头,决定以后将研究过的东西写到博客里,方便自己以后查找,也方便技术分享.第一篇从基础的自定义下拉刷新开始.这里说下,我是在大神的肩膀上进行自定义的,因为自己重写下拉刷新的话会有很多 ...
最新文章
- 服务器虚拟化使用报告,服务器虚拟化可行性报告
- window.onload 不执行
- 模拟电路技术之基础知识(五)
- ubuntu服务器安装指南
- wait()和sleep()
- Scala中的while循环
- 京东ajax怎么用,使用Ajax、json实现京东购物车结算界面的数据交互实例
- ssm项目启动,加载数据库连接池时卡住
- 订单同步工程标准化改造事记
- python写给初学者的一封信
- MySQL5.0安装图文教程
- 如何创建GOOGLE ADS的MCC经理账户,有什么好处?
- 使用NetKeeper导致电脑右下角任务栏网络图标消失不见的解决方法
- 噪音达到多少分贝就算是扰民
- 云呐|固定资产调拨流程(固定资产调拨需要哪些流程)
- 梦想经不起等待 -- 美文转载
- linux scp文件传输
- vs2017支持所有版本VC
- Zabbix的SNMPTrap监控配置
- k8s存储PV与PVC使用详解