仿饿了么下拉刷新

2023-10-23 07:38
文章标签 刷新 仿饿

本文主要是介绍仿饿了么下拉刷新,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用RecyclerView仿饿了么下拉刷新

经常用饿了么点餐,看到这个下拉刷新,模仿一波。

效果图

Step1

自定义EleView.这个view就是根据RecyclerView的onTouch移动的距离,显示处理篮子打开和冒出水果的动画。这里有两个偏移,坐标(篮子位移)与角度(篮子盖打开)偏移,所以需要一个onMove方法统一传入偏移的百分百percent,再计算和重绘。

 public void onMove(float percent) {if (percent >= 0.6) {currentDegree = (float) (150 * (percent - 0.6) * 2.5);}if (percent <= 1) {offsetY = percent * maxOffsetY;invalidate();}}

在onDraw方法里面可以先绘制静态的图,在根据偏移统一调整坐标和角度。这里篮子有个迷の带感的震动效果,实现也是用属性动画:

    cycleAnimator = ValueAnimator.ofFloat(-1, 1);cycleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentOffset = (float) animation.getAnimatedValue();invalidate();}});......

通过currentOffset变化,影响绘制的canvas.drawBitmap传入的Rect dst的坐标,造成影像的缩放。

  @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.translate(mWidth / 2, offsetY);for (int i = 0; i < 5; i++) {dstFruit.left = (int) (mPosition0[i][0] - 0.5 * fW);dstFruit.top = (int) (mPosition0[i][1] - 0.5 * fH);dstFruit.right = (int) (mPosition0[i][0] + 0.5 * fW);dstFruit.bottom = (int) (mPosition0[i][1] + 0.5 * fH);if (foods.get(i).showing) {canvas.drawBitmap(foods.get(i).bitmap, null, dstFruit, paint);}}canvas.save();int offsetC = (int) (currentOffset * 5);canvas.rotate(currentDegree, (float) (dstE.right - iWidth * scale / 4), (float) (dstE.top + scale * iWidth));canvas.drawBitmap(iR, null, new Rect(dstI2.left, dstI2.top - offsetC, dstI2.right, dstI2.bottom + offsetC), paint);canvas.restore();canvas.save();canvas.rotate(-currentDegree, (float) (dstE.left + iWidth * scale / 4), (float) (dstE.top + scale * iWidth));canvas.drawBitmap(iL, null, new Rect(dstI.left, dstI.top - offsetC, dstI.right, dstI.bottom + offsetC), paint);canvas.restore();canvas.drawBitmap(ele, null, new Rect(dstE.left, dstE.top - offsetC, dstE.right, dstE.bottom + offsetC), paint);}

水果移动需要得到水果移动的路径,在根据路径算出坐标。路径很好得到,大概估计一下就行。获取到路径在获取每个点的坐标,这里用到了PathMeasure的getPosTan(float distance, float pos[], float tan[]),简单的说就是把这个路径拉直成一条直线,然后根据当前位移获取当前的坐标,封装到数组中去。由于现在有5个水果需要移动,新建二位数组mPosition0 = new float[5][2];

 for (int i = 0; i < 5; i++) {final int finalI = i;ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.get(finalI).getLength());valueAnimator.setDuration(duration);valueAnimator.setInterpolator(new DecelerateInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float value = (Float) animation.getAnimatedValue();// 获取当前点坐标封装到mCurrentPositionmPathMeasure.get(finalI).getPosTan(value, mPosition0[finalI], null);postInvalidate();}});}

Step2

新建一个MyHeaderView 继承LinearLayout。这里为了方便以后的拓展,抽取一个接口:之后只要实现了这个接口,就可以传入到ERecyclerView充当刷新的HeadView。

public interface Header {int STATE_NORMAL = 0;int STATE_READY = 1;int STATE_REFRESHING = 2;int STATE_DONE = 3;void setVisibleHeight(int height);int getVisibleHeight();void setState(int state);void onMove(float delta);void refreshComplete();boolean releaseAction();
}

Step3

自定义RecyclerView主要是处理当onTouchEvent。其实还有其他的地方但不是本文的重点。

.....private Header headerView;@Overridepublic boolean onTouchEvent(MotionEvent e) {if (mLastY == -1) {mLastY = e.getRawY();}if (isOnTop() && !isloading) {switch (e.getAction()) {case MotionEvent.ACTION_DOWN:mLastY = e.getRawY();break;case MotionEvent.ACTION_MOVE:float delta = e.getRawY() - mLastY;mLastY = e.getRawY();headerView.onMove(delta / 1.5f);break;default:if (headerView.releaseAction() && freshListener != null && !isloading) {noMore = false;isloading = true;freshListener.onRefresh();}mLastY = -1;break;}}return super.onTouchEvent(e);}

差不多就这些,没错就是这么短小精悍!还有其他的具体代码细节请看项目源码,如果觉得不错顺手点个star也是极好的O(∩_∩)O哈哈~:
https://github.com/Ulez/ERecyclerView

这篇关于仿饿了么下拉刷新的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/266469

相关文章

自定义布局实现listview上拉加载下拉刷新

listview布局有时加载数据偏多,需要上拉加载第二页等更多数据,下拉刷新数据等功能,也有开源的框架XRefreshView ,可以参考http://www.w2bc.com/Article/44291,当初开发项目时,便于自己控制,就自定义布局实现这功能。 1、自定义布局用来管理三个子控件:下拉头,包含内容的自定义listview,上拉头(代码有详细介绍) public class Pul

vue列表数据删除后刷新页面

目录 背景页面刷新方式1.原始方法2.vue自带的路由跳转3.重新调用获取数据列表的接口4.使用provide和inject实现页面刷新使用方式总结 背景 在页面进行增删改列表后,页面需要进行刷新,在进行这些操作后,需要手动刷新才能更新列表。本文主要讨论进行增删改查相关操作后如何使当前页面显示操作后的最新数据。 参考:vue实现在进行增删改操作后刷新页面 页面刷新方式

button 提交后再次刷新页面

button,input type=button按钮在IE和w3c,firefox浏览器区别 当在IE浏览器下面时,button标签按钮,input标签type属性为button的按钮是一样的功能,不会对表单进行任何操作。 但是在W3C浏览器,如Firefox下就需要注意了,button标签按钮会提交表单,而input标签type属性为button不会对表单进行任何操作。 解决方案:

C1-2 ABB二次SDK开发——手把手教登录对应的机器人控制器(图片引导操作)登录机器人控制器和刷新机器人列表

1.完成配置后我们开始进行操作 C1-1 ABB二次SDK开发——C#Window窗体-环境配置(带ABB二次开发SDK资源包)-CSDN博客文章浏览阅读95次。3.记住路径,右键C#引用,然后导入ABB.Robotics.Controllers.PC.dll。2.安装资源文件PCABB二次开发的SDK,并打开安装路径。1.新建VSC#的windowfrom项目。4.在框架代码主界面代码中添加。

动态刷新ListView

要刷新ListView,只需要调用其适配器的notifyDataSetChanged()方法即可。 下面的例子是在“ListView的例子”的基础上演化而言,本文仅给出变化的部分。 布局文件:增加了一个按钮,动态增加一个学生记录。 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http:

jsp页面点击页签自动刷新解决方案

问题:在一个projectInfoMain.jsp的界面定义了多个页签,怎么实现在一个页签的jsp页面保存完以后点击每个页签时自动刷新改界面。 解决方案:可以在每次点击页签时,修改页签的url地址,使它再次向服务器发送请求,以实现自动刷新的功能 具体解决方案: projectInfoMain.jsp主界面实现代码: <%@ page language="java" cont

bug系列-------home界面自动刷新

最近遇到一个bug,setting里将display设置为never sleep之后返回home界面,系统会不断刷新,看了一下log发现下面一段有问题 09-20 03:41:42.013  5974  5974 D PowerSaverUpdateIcon: send broadcast to update animated icon 09-20 03:41:42.013  5974  597

ajax学习之xml数据处理实例(网页注册用户名无刷新检测)

文件 reg.php <html> <head> <title>用户注册</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> </head> <body> <form action="???" method="post">     用户名字:<input type="text"  οnkey

XRefreshView集成以及自定义下拉刷新动画

 XRefreshView集成以及自定义GIF动画 1继承第三方库    compile 'com.huxq17.xrefreshview:xrefreshview:3.6.9'     //依赖下面的库不然会报错    compile 'com.android.support:recyclerview-v7:23.0.1' 2项目xml使用

flutter key和globalkey如何使用及局部刷新

key和globalkey的使用,在实际开发中还是经常使用到的,尤其是globalkey设置到局部刷新会经常用到,例如TextView局部刷新等,还有其它任何控件需要局部刷新的也可以通过globalkey来实现,下面会有详细介绍。 key是标识widget的唯一性,组件能不能复用和更新主要通过key和组件的类型(runtimeType)来判断,如果key不传,则会判断组件的类型,globalke