利用NestedScrolling机制改造SwipeRefreshLayout

本文介绍了如何利用NestedScrolling机制改造SwipeRefreshLayout以实现上拉刷新功能。通过分析NestedScrollingChild和NestedScrollingParent接口,以及使用NestedScrollingChildHelper和NestedScrollingParentHelper辅助类,详细讲解了改造过程,包括参数测量、配合滑动、结束滑动的处理。同时,文章提供了项目的GitHub地址供读者参考。
摘要由CSDN通过智能技术生成

参考文章:

https://segmentfault.com/a/1190000002873657
http://blog.csdn.net/al4fun/article/details/53888990

一、NestedScrolling机制

吐槽:之前笔者在设计的时候,想在ViewPager的页面上实现仿微信的左滑删除,但是怎么都实现不了,因为其中跟ViewPager的滑动冲突了,当时才疏学浅(现在也是),进了很多坑,比如滑动的拦截、滑动事件在Down之后会跳过判断等,在没有系统学习过这方面知识的情况下以大败告终。
所以,谷歌人性化地推出了这个机制,滑动之前和爸爸商量一下,一切多么融洽,和之前盲人摸象的方式相比人性化多了。

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

2.接口

NestedScrollingChild

//开始滑动
public boolean startNestedScroll(int axes);
//停止滑动
public void stopNestedScroll();
//在滑动前,进行滑动事件分配(询问),consumed是父亲消耗的滑动距离,offsetInWindow
//是父亲在窗口中进行的相应的移动,子view需要根据这个进行自身调整(需要的话)
//区别于下面的,在这里可以进行父亲预备处理
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);
//滑动后滑动事件的分配,子view询问父亲是否需要在滑动后消耗事件
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);

//惯性滚动相关
public boolean dispatchNestedPreFling(float velocityX, float velocityY);
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);

NestedScrollingParent

//当子view开始滑动时调用,可以在这里选择是否要与子view嵌套滑动,从而返回boolean
//其中target是发起滑动的对象,child是包含target的子view,nestedScrollAxes是方向标志位
//SCROLL_AXIS_HORIZONTAL 或 SCROLL_AXIS_VERTICAL
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);
//老实说我觉得这个方法在有了上面的onStartNestedScroll之后就有点鸡肋了
public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);
//结束滑动时调用
public void onStopNestedScroll(View target);

//在子滑动之前调用
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed);
//在子滑动之后调用    
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed);

//当惯性嵌套滚动时被调用
public boolean onNestedPreFling(View target, float velocityX, float velocityY);
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed);

3.帮助类

NestedScrollingChildHelper
NestedScrollingParentHelper

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

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

这里写图片描述

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


二、实例演示:改造SwipeRefreshLayout

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

成果:
这里写图片描述<

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值