Android 下拉刷新最开始源于 ios 系统的体验,后来国外的 johannilsson 写了第一份开源控件(https://github.com/johannilsson/android-pulltorefresh),后来许多国内的码农在此基础之上修改了很多,但是体验不尽完好,最终找到了 chrisbanes (https://github.com/chrisbanes/Android-PullToRefresh) 写的版本,现在应该有很多更新了吧。
作者也是在johannilsson 的基础之上进行修改,然后加上了对 expandlistview, gridview ,webview,scrollview,viewpager ,listfragment等等的支持,可谓举一反三呀。话说控件原理不难,但是写起来时,却尽是细节,能够写的这么规范,可见功力也不一般。

摘自:http://blog.csdn.net/fei5050/article/details/8442566


最近在学习android下拉刷新的功能,完成了简单的使用,在这里总结一下。
我一共找到三个相关的demo,其中前两个记不起来在哪里找到的了,先在这里默默地感谢大神。

第一个demo(NLPullRefreshViewDemo):

1.布局:自己写一个组件命名曰NLPullRefreshView继承自LinearLayout,在NLPullRefreshView里有一个ListView占满NLPullRefreshView,再inflate一个View,设置该View宽度和NLPullRefreshView一样宽,高度wrap_content,设置它上边距为它高度的相反数,这样他就在ListView的上面的,也就是在屏幕的上面隐藏起来了。
2.事件响应:外面是NLPullRefreshView,里面有一个ListView,一个touch事件到底是被谁响应呢?我的理解是用ViewGroup里的回调函数onInterceptTouchEvent来区分出来是谁响应Touch事件。如果onInterceptTouchEvent返回false,则touch事件传到ListView里面;如果onInterceptTouchEvent返回true,则事件不会再传递到ListView里,这样Touch事件就可以被NLPullRefreshView的onTouchEvent方法处理。关于ViewGroup的onInterceptTouchEvent在下一篇博文里总结。

第二个demo(TestPullAndRefresh):

1.布局:写一个组件继承自MyListView,再inflate一个View,添加到ListView的上面,用void android.widget.ListView.addHeaderView(View v, Object data, boolean isSelectable)这个方法添加的。其中添加的过程中用到过Measure这个方法,关于android的界面的绘制,Measure->layout->draw,一直都是云里雾里,那位大神有这方面的资料给分享一下,先感谢了。
2.事件响应:这里事件响应就比较简单了,只有一个ListView。在onScroll方法里,判断一下ListView的第一个列表项是否在最上面来区别是不是下拉显示Header。因为事件响应和上面的demo不同,有一个现象体现这里的不同,按住ListView往上滑动一点,再向下滑动,在第一个demo里不显示Header,在第二个demo里显示Header。
3.状态:这个demo里定义了5种状态,这个demo里在onTouchEvent里改变一个状态,接着调用通过状态调整一下布局的方法,在该方法里做个动画,5种状态足以表示touchUp之后的状态了。

总结一下这两个demo:

1.从布局来说,不论是继承LinearLayout还是继承ListView,都是ViewGroup,都是在ViewGroup里两个View。
2.都用了状态,显然下拉的不同程度,Header的状态是不一样的。
3.从事件响应来说,都是处理onTouchEvent方法,并且在处理之前要判断一下是否开始Header的下拉,如果是下拉的话,通过Touch事件y坐标的变化设置Header的位置,前一个demo设置用的是Header的上外边距(LayoutParams.topMargin),下一个demo用的是内边距(headerView.setPadding(0, -1 * headerContentHeight, 0, 0))。
这里一般还有个接口,再调一下接口里的方法,让外面实现该接口的类做具体的刷新工作。
4.功能比较单一,比如说我想用上拉刷新,就要码很多代码。

第三个demo(PullToRefresh):

正如前面仁兄提到的这位大神能想的这么规范真是很了不起,学习了。我粗略地数了一下库项目有4600行代码,虽然从代码量上来说,并不是特别多,但是基本没有注释,变量还挺多,仅根据变量的那个英文的名字很难猜到它到底是干嘛用的,并且调用比较复杂,有时还出现个我没有见过的类,更关键的是这是我第一次看这么复杂的项目,一时间没有理解透彻,下面一个目标就是深入理解这个大神的思路。下面简单总结一下我对这个demo的理解。
1.最重要的一个类应该是
public abstract class PullToRefreshBase<T extends View> extends LinearLayout implements IPullToRefresh<T> 
它了,和前面两个demo相似,其实都是继承自ViewGroup,为了能让更多的组件实现下拉刷新而不只是ListView,该类使用泛型并且是<T extends View>,意思是View都可以,在他给的demo里就有webview的,Viewpager的,等等各种吧。
2.PullToRefreshBase里面几个重要的View, T mRefreshableView; 这个是可以滑动的View,还有

private LoadingLayout mHeaderLayout;private LoadingLayout mFooterLayout;
LoadingLayout继承自FrameLayout,就是刷新的头和尾了,这里支持下拉刷新和上拉刷新,这分别是他们的View,有一个枚举变量标识当前的模式,有一个枚举变量标示当前的状态。
3.该库事件处理也是onInterceptTouchEvent和onTouchEvent,在onInterceptTouchEvent里有滑动方向的判断,因为支持左拉和右拉刷新。
4.虽然库看起来比较难懂,但是用起来相对要简单一些,只要用哪个类,再做个布局,最后实现个回调接口就完事了。在用ViewPager里的ListView的下拉刷新时与到一个小问题,其实ViewPager里的Item就是PullToRefreshListView(该类继承自PullToRefreshBase<ListView>),在demo里的事件响应里没有区别是ViewPager的哪个Item做的刷新。设置刷新回调函数,该函数的参数是

public void onRefresh(PullToRefreshBase<ListView> refreshView) {new GetDataTask(refreshView).execute();}
从这个对象中不能确定他是ViewPager的第几个Item,我在PullToRefreshBase类里添加了个属性,用它来标示PullToRefreshBase的身份,或许PullToRefreshBase里有标示身份的属性吧,只是我没有找到而已。就拿PullToRefreshBase<ListView>来说,该对象可以得到里面的ListView,用这个ListView对象可以得到Adapter对象,刷新列表里的数据都是用Adapter.notifyDataSetChanged()方法,但是用前面得到的ListView得到的Adapter对象是ListAdapter类型的,从继承关系上看它没有.notifyDataSetChanged()方法,所以Adapter对象必须得自己去维护,所以在ViewPager里的ListView的刷新回调函数执行的时候必须得知道它的身份,才能找到对应的Adapter才能进行刷新。

源码下载:

前两个demo的下载地址:https://github.com/bingoSpunky/pulltorefreshdemo
大神的demo的下载地址:https://github.com/chrisbanes/Android-PullToRefresh

更多相关文章

  1. SwipeRefreshLayout + RecyclerView 实现 上拉刷新 和 下拉刷新
  2. Android的事件转递机制
  3. Android实现三级联动下拉框 下拉列表spinner
  4. pull解析
  5. 【转载】Android事件分发机制完全解析,带你从源码的角度彻底理解(
  6. Android(安卓)Notification通知栏、点击事件、悬浮通知的简单实
  7. Android(安卓)事件触发机制
  8. Android热插拔事件处理流程--Vold
  9. Android中Touch手势分发

随机推荐

  1. Android(安卓)数字签名
  2. Android(安卓)学习 笔记_01
  3. android的Sprite,TiledLayer,LayerManage
  4. 聊聊Android(安卓)热修复Nuwa有哪些坑
  5. Android之地址服务
  6. Android(安卓)HttpURLConnection及HttpCl
  7. Android自定义Toast的时长、位置、及显示
  8. 在Android当中常用的控件的详解和分析
  9. 在 Android(安卓)上使用 RxNetty
  10. Android4.1.2 Email发送邮件附件中文名乱