Android 改造SwipeRefreshLayout 支持上拉加载

原文链接 : http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650822399&idx=1&sn=9cc9c74d063cc00c6820bdfefc6bf518&chksm=80b78261b7c00b7799577b10a42f598249b02d3bc1d22f281be0391807d103477ccaad9dfc82&mpshare=1&scene=23&srcid=0323qkEeDyK3MOkfXs3LaNYh%23rd

请支持原文作者 : 鸿洋

看到这个文章我才想起来,今天推荐一个项目,是我的一位好朋友之前在创业公司的一个项目,后来项目失败了,经允许后将源码分享出来了,该项目也对SwipeRefreshLayout进行了扩展,支持了上拉,如果有实际需求,不妨也试下这个(项目质量非常高)。

https://github.com/pinguo-sunjianfei/Android-Application-ZJB

ps:该项目服务端已经停了,所以只能看代码了,运行不起来了~~

本文作者

本文由Get_Zoom投稿。
Get_Zoom的博客地址:
http://blog.csdn.net/Get_Zoom

1

NestedScrolling机制

之前笔者在设计的时候,想在ViewPager的页面上实现仿微信的左滑删除,但是怎么都实现不了,因为其中跟ViewPager的滑动冲突了,当时才疏学浅(现在也是),进了很多坑,比如滑动的拦截、滑动事件在Down之后会跳过判断等,在没有系统学习过这方面知识的情况下以大败告终。

所以,谷歌人性化地推出了这个机制,滑动之前和父控件商量一下,一切多么融洽,和之前盲人摸象的方式相比人性化多了。

(1)滑动流程

子view获取到点击事件后,询问父亲是否需要配合滑动,然后每一次滑动之前都会询问父亲,并记录下父亲消耗的滑动距离,在上面完成后才进行自己自身的滑动。

(2)接口

NestedScrollingChild

NestedScrollingParent

(3)帮助类

NestedScrollingChildHelper NestedScrollingParentHelper

故名思义,上面的帮助类帮助我们处理了上面父子接口的方法。

它们帮助我们实现了逻辑上的方法,在一些情况下我们只希望处理子接口或者父接口,为了对接可以在另一个接口使用帮助类(比如下面的实例,改造SwipeRefreshLayout,我们更希望作为父亲处理子view事件而滑动自身,对于上层组件(父)不是很关心,就可以使用NestedScrollingParentHelper来方便编程。

借用网上的一张图,可以看到两个接口之间的对应关系:

图片来源:https://segmentfault.com/a/119000000287365

2

实例演示:改造SwipeRefreshLayout

(1)目的
SwipeRefreshLayout就是一个实现了NestedScrolling机制的控件,可以方便的实现下拉刷新。

现在我们想加上上拉刷新功能,可以反着做,给下方加一个可拉动的控件(小圆圈),然后处理它的滑动事件。为了能兼顾上层,我们再外面还加了常规的CoordinatorLayout和AppBarLayout作为测试。

成果:


(2)准备工作
改造之前当然要先把人家之前的成果准备好。



首先当然是把我们的SwipeRefreshLayout移过来,可以换一个名字避免以后的冲突。

然后布局中要用到两个控件,一个是CircleImageView,也就是显示的小圆圈,附带阴影功能;一个是MaterialProgressDrawable,用于在CircleImageView显示进程(颜色滑动)。

在移动的时候SwipeRefreshLayout会报错,报错时把东西移动过来就行了。
然后阅读源码,我们暂时只处理NestedScrolling机制,所以一般的移动流程比如onTouchEvent可以先放着,以后为了和其他不带NestedScrolling控件兼容的时候再改进。

(3)开始改造工作
**1.参数测量 **
一个主要的问题就是,我们下面的圆圈(加载圈,以下简称圆圈)要放在哪?

原生的直接放在中间然后上去一个圆圈身位的地方,所以下面圆圈水平位置一样,竖直的话就放在屏幕下方。

综合测试出这样的距离比较好:

所以相应的位置放置我们就这样:

2.作为父控件配合滑动


a.是否配合滑动

这里我们只增加了一个上拉刷新标志位

这里也是,只是增加了mTotalUnconsumedBottom ,这是我们上拉刷新的未消费路程。

b.滑动之前

我们可以看到源码中的onNestedPreScroll有这么一段处理:

在滑动前先判断,我们未消费滑动路程是否还有,有则判断方向,如果是滑动的反方向,也就是我们再下拉刷新一半的时候又往回拉,这时做出处理,选择消费当前滑动路程。

所以我们可以写出下方的拖动预处理:

这里有个坑要提醒下,一开始笔者自作聪明,觉得consumed参数应该传绝对值,导致后来往回滑的时候子控件跑得飞快(可以想想为什么),所以这里消费了负的路程就传回负的路程,可以看看源码中NestedScrollingChildHelper的实现。

c.正式滑动

这个反而比较容易,只需要加上判断当前子控件还能不能往上滑。

滑动处理:

大概解释一下,我们的滑动时分段的,在mTotalDragDistance滑动之前是线性的,在这之后会做一个加速的处理,最多延伸一个mSpinnerOffsetEnd
在实际的view位置改变中,我们使用的是
setTargetOffsetTopAndBottomForBottom (targetY-mCurrentTargetOffsetBottom, true);

这个方法,里面是采用
ViewCompat.offsetTopAndBottom

来改变view的位置的。

d.结束滑动

如果手指离开的时候,拖动距离不为零,那么我们要做判断,做出相应的处理

可以看到主要有两种处理,以mTotalDragDistance为界限,超过这个滑动距离我们就显示刷新,没有的话就动画回到原点。

**3.作为子控件配合滑动 **
我们知道,AppBarLayout和CoordinatorLayout会配合滑动,子view往上滑的时候会隐藏,如果不做处理,在下端圆圈滑动到一半的时候往回滑会把AppBar又拖出来,消费滑动事件,所以我们选择拦截,在下部圆圈滑动的时候优先处理滑动:

到这里,我们的控件就基本完成了,当然谷歌出版的控件,动画效果是不能少的,它的美观也体现在这里,由于基本是能模仿的,所以这里不再多讲。这个控件的改造主要麻烦在它的动画衔接以及滑动处理机制(加速等),剩下的都很好理解,建议大家动手试一试。

项目地址:
https://github.com/SGZoom/DailyWidget/tree/master/widgetpro

文章跟代码可能包含很多不足之处,欢迎大家帮忙指出错误与不足,谢谢~

参考文章:
https://segmentfault.com/a/1190000002873657

http://blog.csdn.net/al4fun/article/details/53888990

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,082评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,231评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,047评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,977评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,893评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,976评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,605评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,888评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,906评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,732评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,513评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,980评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,027评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,232评论 2 339

推荐阅读更多精彩内容