说到下拉刷新,相信大家都不陌生,现在基本上每个项目都会用到。我们公司的项目一直都是使用SwipeRefreshLayout,官方的Material Design风格,好用少Bug。现在下拉刷新大概有下面几种实现方式:一种是直接包在ListView或者RecyclerView的头部,有的则是像SwipeRefreshLayout一样,包在视图的最外层,个人建议使用包在最外层的做法,可拓展性比较强。下面用包在最外层的方法实现京东和天猫的下拉刷新。

1.使用框架android-Ultra-Pull-To-Refresh

https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh

大家有兴趣的可以去看一下这个下拉刷新框架,可拓展性非常强,兼容各种View的下拉刷新事件。

2.京东下拉刷新

先看看京东的下拉刷新动画:

从上图可以看出,就是一个动画,当然截图有点卡,首先,我们解压手机京东的app,得到上面的图片:

先看看头部刷新的布局怎么实现:

jd_refresh_header_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><FrameLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@+id/layout_tx"><ImageViewandroid:id="@+id/iv_man"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/a2a" /><ImageViewandroid:id="@+id/iv_goods"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="right|center"android:src="@drawable/a29" /></FrameLayout><LinearLayoutandroid:id="@+id/layout_tx"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:layout_marginLeft="5dp"android:gravity="center_vertical"android:orientation="vertical"android:padding="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="让购物更便捷"android:textSize="14sp" /><TextViewandroid:id="@+id/tv_remain"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:text="松开刷新"android:textSize="12sp" /></LinearLayout>
</RelativeLayout>

咱们再看看android-Ultra-Pull-To-Refresh这个框架:

package in.srain.cube.views.ptr;import in.srain.cube.views.ptr.indicator.PtrIndicator;/****/
public interface PtrUIHandler {/*** When the content view has reached top and refresh has been completed, view will be reset.** @param frame*/public void onUIReset(PtrFrameLayout frame);/*** prepare for loading** @param frame*/public void onUIRefreshPrepare(PtrFrameLayout frame);/*** perform refreshing UI*/public void onUIRefreshBegin(PtrFrameLayout frame);/*** perform UI after refresh*/public void onUIRefreshComplete(PtrFrameLayout frame);public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator);
}

这是一个下拉刷新事件处理接口,包括准备刷新,开始刷新,刷新完成和刷新改变等事件的处理,直接上代码:

JdRefreshHeader.java

package com.jackie.pulltorefresh.jd;import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;import com.jackie.pulltorefresh.R;import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.indicator.PtrIndicator;/*** 下拉刷新HeaderView*/
public class JdRefreshHeader extends FrameLayout implements PtrUIHandler {/*** 提醒文本*/private TextView mTvRemind;/*** 快递员logo*/private ImageView mIvMan;/*** 商品logo*/private ImageView mIvGoods;/*** 状态识别*/private int mState;/*** 重置* 准备刷新* 开始刷新* 结束刷新*/public static final int STATE_RESET = -1;public static final int STATE_PREPARE = 0;public static final int STATE_BEGIN = 1;public static final int STATE_FINISH = 2;public static final int MARGIN_RIGHT = 100;/*** 动画*/private AnimationDrawable mAnimationDrawable;public JdRefreshHeader(Context context) {this(context, null);}public JdRefreshHeader(Context context, AttributeSet attrs) {this(context, attrs, 0);}public JdRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView();}/*** 初始化view*/private void initView() {View view = LayoutInflater.from(getContext()).inflate(R.layout.jd_refresh_header_view, this, false);mTvRemind = (TextView) view.findViewById(R.id.tv_remain);mIvMan = (ImageView) view.findViewById(R.id.iv_man);mIvGoods = (ImageView) view.findViewById(R.id.iv_goods);addView(view);}@Overridepublic void onUIReset(PtrFrameLayout frame) {mState = STATE_RESET;}@Overridepublic void onUIRefreshPrepare(PtrFrameLayout frame) {mState = STATE_PREPARE;}@Overridepublic void onUIRefreshBegin(PtrFrameLayout frame) {mState = STATE_BEGIN;//隐藏商品logo,开启跑步动画mIvGoods.setVisibility(View.GONE);mIvMan.setBackgroundResource(R.drawable.runningman);mAnimationDrawable = (AnimationDrawable) mIvMan.getBackground();if (!mAnimationDrawable.isRunning()) {mAnimationDrawable.start();}}@Overridepublic void onUIRefreshComplete(PtrFrameLayout frame) {mState = STATE_FINISH;mIvGoods.setVisibility(View.VISIBLE);//停止动画if (mAnimationDrawable.isRunning()) {mAnimationDrawable.stop();}mIvMan.setBackgroundResource(R.drawable.a2a);}@Overridepublic void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {//处理提醒字体switch (mState) {case STATE_PREPARE://logo设置mIvMan.setAlpha(ptrIndicator.getCurrentPercent());mIvGoods.setAlpha(ptrIndicator.getCurrentPercent());LayoutParams params = (LayoutParams) mIvMan.getLayoutParams();if (ptrIndicator.getCurrentPercent() <= 1) {mIvMan.setScaleX(ptrIndicator.getCurrentPercent());mIvMan.setScaleY(ptrIndicator.getCurrentPercent());mIvGoods.setScaleX(ptrIndicator.getCurrentPercent());mIvGoods.setScaleY(ptrIndicator.getCurrentPercent());int marginRight = (int) (MARGIN_RIGHT - MARGIN_RIGHT * ptrIndicator.getCurrentPercent());params.setMargins(0, 0, marginRight, 0);mIvMan.setLayoutParams(params);}if (ptrIndicator.getCurrentPercent() < 1.2) {mTvRemind.setText("下拉刷新...");} else {mTvRemind.setText("松开刷新...");}break;case STATE_BEGIN:mTvRemind.setText("更新中...");break;case STATE_FINISH:mTvRemind.setText("加载完成...");break;}}
}

创建一个成员变量mState,用于保存下拉刷新的时候,每一个状态,然后根据保存好的状态在UIPositionChange的接口中,对UI进行相应的修改,保存每个状态文本的提示,在下拉的过程中,通过UIPositionChange的回调,获取PtrIndicator中,可以获取下拉的百分比,根据这个百分比我们可以做很多东西,例如京东的快递小哥从远处跑过来拿商品,以及快递小哥与商品之间的大小,都可以根据这个PtrIndicator百分比进行设置其大小的比例,跑过来这个过程我使用的方法是利用marginRight进行设置两者之间的距离,当达到下拉刷新的临界点时,快递小哥跟商品之间的margin为0,达到了快递小哥获取商品的效果,然后当刷新的时候,隐藏商品,使用之前所提供的三张图片进行效应的切换,也就是动画:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"><itemandroid:drawable="@drawable/a2b"android:duration="70" /><itemandroid:drawable="@drawable/a2c"android:duration="70" /><itemandroid:drawable="@drawable/a2d"android:duration="70" />
</animation-list>

效果图如下:

3.天猫下拉刷新
天猫的更简单,毫无动画可言,说白了就是个GIF,大家可以去下载个apk,解压后能得到其gif。原理跟之前的是一样,但这里我使用的是fresco进行加载gif,方法有很多,大家感兴趣的可以去试试。

TmallRefreshHeader.java

package com.jackie.pulltorefresh.tmall;import android.content.Context;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.jackie.pulltorefresh.R;import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.indicator.PtrIndicator;/*** 下拉刷新HeaderView*/
public class TmallRefreshHeader extends FrameLayout implements PtrUIHandler {/*** 提醒文本*/private TextView mTvRemind;/*** 状态识别*/private int mState;/*** 重置* 准备刷新* 开始刷新* 结束刷新*/public static final int STATE_RESET = -1;public static final int STATE_PREPARE = 0;public static final int STATE_BEGIN = 1;public static final int STATE_FINISH = 2;public TmallRefreshHeader(Context context) {this(context, null);}public TmallRefreshHeader(Context context, AttributeSet attrs) {this(context, attrs, 0);}public TmallRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView();}/*** 初始化view*/private void initView() {View view = LayoutInflater.from(getContext()).inflate(R.layout.tmall_refresh_header_view, this, false);mTvRemind = (TextView) view.findViewById(R.id.tv_remind);SimpleDraweeView sdv = (SimpleDraweeView) view.findViewById(R.id.tm_logo);DraweeController draweeController = Fresco.newDraweeControllerBuilder().setAutoPlayAnimations(true)//设置uri,加载本地的gif资源.setUri(Uri.parse("res://" + getContext().getPackageName() + "/" + R.drawable.tm_mui_bike))//设置uri.build();sdv.setController(draweeController);addView(view);}@Overridepublic void onUIReset(PtrFrameLayout frame) {mState = STATE_RESET;}@Overridepublic void onUIRefreshPrepare(PtrFrameLayout frame) {mState = STATE_PREPARE;}@Overridepublic void onUIRefreshBegin(PtrFrameLayout frame) {mState = STATE_BEGIN;}@Overridepublic void onUIRefreshComplete(PtrFrameLayout frame) {mState = STATE_FINISH;}@Overridepublic void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {//处理提醒字体switch (mState) {case STATE_PREPARE:if (ptrIndicator.getCurrentPercent() < 1) {mTvRemind.setText("下拉刷新");} else {mTvRemind.setText("松开立即刷新");}break;case STATE_BEGIN:mTvRemind.setText("正在刷新...");break;case STATE_FINISH:mTvRemind.setText("加载完成...");break;}}
}

效果图如下:

最后附上github地址:

https://github.com/shineflower/JdTmallPullToRefresh

Android高仿京东、天猫下拉刷新相关推荐

  1. android高仿网易新闻上下拉刷新,仿网易新闻最新版的下拉刷新

    今天一天做了一个仿照网易的下拉刷新,先上效果图: 代码还有一点问题.我先说怎么用把: 1.   布局文件. xmlns:tools="http://schemas.android.com/t ...

  2. 快速仿写京东、天猫下拉刷新

    好久没输出文章了,最近研发任务比较忙,果然计划赶不上变化,之前还希望能一周一输出,好吧,我还是承认自己比较懒好了,=.=## 这次跟大家分享一下下拉刷新,之前我们的公司的项目一直都是使用SwipeRe ...

  3. Android仿苹果版QQ下拉刷新实现(三)

    前言 第三篇下拉刷新的博客来的稍微有点晚,因为前两篇的博客访问量一直不是很高,所以博主花了点时间修改了整体的Demo效果,处理了很多极端下拉情况下的显示问题,给大家呈现一个完美的下拉刷新控件.因为本文 ...

  4. Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发鼻涕下拉粘连效果

    前言 接着上一期 Android仿苹果版QQ下拉刷新实现(一) --打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效 ...

  5. android高仿京东快报(垂直循环滚动新闻栏)

    的android高仿京东快报(垂直循环滚动新闻栏) 标签: 机器人 2016年3月20日03:08 2676阅读人 评论(15)收藏举报    分类: 机器人(71)  版权声明:本文为博主原创文章, ...

  6. vue 仿B站下拉刷新上拉加载

    vue 仿B站下拉刷新上拉加载 功能大部分都是跟B站一样的,还是有一些瑕疵和小bug的,φ(>ω<*) 先上demo连接和gitHub项目地址吧 demo展示 https://github ...

  7. Android 高仿唱吧 咔拉ok 商业项目开源代码 K歌合成 伴奏录音合成MP3(音频五)

    Android MediaRecorder录音录像 暂停 继续录音 播放 ARM格式(音频一) https://blog.csdn.net/WHB20081815/article/details/88 ...

  8. android禁止下拉刷新,Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下 ...

  9. android高仿京东app

    仿京东app 采用组件化架构 屏幕适配方案可以较好解决多分辨率及同分辨率不同dpi适配: 全新组件化架构升级,相比之前的方案模块间更为解耦且使用更为方便: 本项目为仿京东项目,资源为抓包获取,项目框架 ...

最新文章

  1. 使用深度学习检测DGA(域名生成算法)——LSTM的输入数据本质上还是词袋模型...
  2. 每一個故事兜發生在狠乆以前
  3. Bootstrap4默认样式不对胃口?教你使用NPM+Webpack+SASS来定制
  4. 京东商城pop开放平台产品经理
  5. 文献学习(part80-B)--Do we Need Hundreds of Classifiers to Solve Real World Classification Problems?
  6. 求n的阶乘的算法框图_单片机常用的14个C语言算法
  7. DOCKER windows 安装Tomcat内容
  8. 数字化风控全流程 实操课程V2.0 第三期
  9. 双层板在哪层覆铜_2020年中国印制电路板行业发展现状及发展趋势预测(图)...
  10. 生意参谋高阶指数换算api、指数换算api、生意参谋交易指数换算api、生意参谋数据查询api
  11. mac怎么无线打印机连接到服务器,Mac连接打印机的方法
  12. 吐血实践-TiDB离线安装
  13. win7电脑蓝屏没有修复计算机,Win7旗舰版系统电脑老是出现蓝屏的修复教程
  14. noi linux黑屏,急!!!noi linux 安装后黑屏怎么处理?(xp系统)
  15. perl中tr的用法
  16. 我为你写下悲伤的文字:伤感心情随笔
  17. 架构--网络关键指标公式
  18. Cascade EF-GAN: 局部聚焦渐进式面部表情编辑
  19. python快速_Python3快速入门
  20. linux dmidecode命令,Linux使用dmidecode命令查看内存型号

热门文章

  1. 35岁的腾讯测试员退休?答:存够2千万回家买房
  2. 计算机教室是在音乐教室旁边吗英语,pep2014年四年级下册期末复习资料
  3. EPC术语(英中文对照)
  4. 计算机int型数值范围
  5. 用于提权的Linux命令,即“xxd”
  6. vue/react高德地图选点组件(坐标拾取工具)
  7. SAP 工作台请求和定制请求的区别
  8. 行内元素与块级元素的区别,行内元素与块级元素分别有哪些
  9. 使用Apache文件上传控件实现文件上传
  10. pythonif循环_三. python 循环if,while,for....