前言

原 来的Android SDK中并没有下拉刷新组件,但是这个组件确实绝大多数APP必备的一个部件。好在google在v4包中出了一个 SwipeRefreshLayout,但是这个组件只支持下拉刷新,不支持上拉加载更多的操作。因此,我们就来简单的扩展一下这个组件以实现上拉下载的 目的。

基本原理

上 拉加载或者说滚动到底部时自动加载,都是通过判断是否滚动到了ListView或者其他View的底部,然后触发相应的操作,这里我们以ListView 来说明。因此我们需要在监听ListView的滚动事件,当ListView滚动到底部时自动触发加载操作;但是当用户支持手指滑动屏幕,没有滚动时,我 们也需要让它加载,因此这种情形就是上拉加载更多。所以我们需要在触摸事件里面进行判断,如果到了底部,且用户是上拉操作,那么执行加载更多。更多关于下 拉刷新、上拉加载请参考[打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)](http://blog.csdn.net/bboyfeiyu/article/details/39718861)。
时间有限,直接上代码吧。

实现代码

**[java]** [view plain](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[copy](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/503362)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/503362/fork)
    <div>
      <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1">
      </embed>
    </div>
  </div>
</div>


  - <span class="comment">/**</span>
  
  - <span class="comment"> * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.</span>
  
  - <span class="comment"> * </span>
  
  - <span class="comment"> * @author mrsimple</span>
  
  - <span class="comment"> */</span>
  
  - <span class="keyword">public</span> <span class="keyword">class</span> RefreshLayout <span class="keyword">extends</span> SwipeRefreshLayout <span class="keyword">implements</span> OnScrollListener {
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 滑动到最下面时的上拉操作</span>
  
  - <span class="comment">     */</span>
  
  - 
  - <span class="keyword">private</span> <span class="keyword">int</span> mTouchSlop;
  
  - <span class="comment">/**</span>
  
  - <span class="comment">     * listview实例</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> ListView mListView;
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 上拉监听器, 到了最底部的上拉加载操作</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> OnLoadListener mOnLoadListener;
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * ListView的加载中footer</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> View mListViewFooter;
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 按下时的y坐标</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">int</span> mYDown;
  
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">int</span> mLastY;
  
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 是否在加载中 ( 上拉加载更多 )</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">boolean</span> isLoading = <span class="keyword">false</span>;
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * @param context</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">public</span> RefreshLayout(Context context) {
  
  - <span class="keyword">this</span>(context, <span class="keyword">null</span>);
  
  - }
  
  - 
  - <span class="keyword">public</span> RefreshLayout(Context context, AttributeSet attrs) {
  
  - <span class="keyword">super</span>(context, attrs);
  
  - 
  - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
  
  - 
  - mListViewFooter = LayoutInflater.from(context).inflate(R.layout.listview_footer, <span class="keyword">null</span>,
  
  - <span class="keyword">false</span>);
  
  - }
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">protected</span> <span class="keyword">void</span> onLayout(<span class="keyword">boolean</span> changed, <span class="keyword">int</span> left, <span class="keyword">int</span> top, <span class="keyword">int</span> right, <span class="keyword">int</span> bottom) {
  
  - <span class="keyword">super</span>.onLayout(changed, left, top, right, bottom);
  
  - 
  - <span class="comment">// 初始化ListView对象</span>
  
  - <span class="keyword">if</span> (mListView == <span class="keyword">null</span>) {
  
  - getListView();
  
  - }
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 获取ListView对象</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">void</span> getListView() {
  
  - <span class="keyword">int</span> childs = getChildCount();
  
  - <span class="keyword">if</span> (childs > <span class="number"></span>) {
  
  - View childView = getChildAt(<span class="number"></span>);
  
  - <span class="keyword">if</span> (childView <span class="keyword">instanceof</span> ListView) {
  
  - mListView = (ListView) childView;
  
  - <span class="comment">// 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载</span>
  
  - mListView.setOnScrollListener(<span class="keyword">this</span>);
  
  - Log.d(VIEW_LOG_TAG, <span class="string">&#8220;### 找到listview&#8221;</span>);
  
  - }
  
  - }
  
  - }
  
  - 
  - <span class="comment">/*</span>
  
  - <span class="comment">     * (non-Javadoc)</span>
  
  - <span class="comment">     * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)</span>
  
  - <span class="comment">     */</span>
  
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">boolean</span> dispatchTouchEvent(MotionEvent event) {
  
  - <span class="keyword">final</span> <span class="keyword">int</span> action = event.getAction();
  
  - 
  - <span class="keyword">switch</span> (action) {
  
  - <span class="keyword">case</span> MotionEvent.ACTION_DOWN:
  
  - <span class="comment">// 按下</span>
  
  - mYDown = (<span class="keyword">int</span>) event.getRawY();
  
  - <span class="keyword">break</span>;
  
  - 
  - <span class="keyword">case</span> MotionEvent.ACTION_MOVE:
  
  - <span class="comment">// 移动</span>
  
  - mLastY = (<span class="keyword">int</span>) event.getRawY();
  
  - <span class="keyword">break</span>;
  
  - 
  - <span class="keyword">case</span> MotionEvent.ACTION_UP:
  
  - <span class="comment">// 抬起</span>
  
  - <span class="keyword">if</span> (canLoad()) {
  
  - loadData();
  
  - }
  
  - <span class="keyword">break</span>;
  
  - <span class="keyword">default</span>:
  
  - <span class="keyword">break</span>;
  
  - }
  
  - 
  - <span class="keyword">return</span> <span class="keyword">super</span>.dispatchTouchEvent(event);
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.</span>
  
  - <span class="comment">     * </span>
  
  - <span class="comment">     * @return</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">boolean</span> canLoad() {
  
  - <span class="keyword">return</span> isBottom() && !isLoading && isPullUp();
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 判断是否到了最底部</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">boolean</span> isBottom() {
  
  - 
  - <span class="keyword">if</span> (mListView != <span class="keyword">null</span> && mListView.getAdapter() != <span class="keyword">null</span>) {
  
  - <span class="keyword">return</span> mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() &#8211; <span class="number">1</span>);
  
  - }
  
  - <span class="keyword">return</span> <span class="keyword">false</span>;
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 是否是上拉操作</span>
  
  - <span class="comment">     * </span>
  
  - <span class="comment">     * @return</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">boolean</span> isPullUp() {
  
  - <span class="keyword">return</span> (mYDown &#8211; mLastY) >= mTouchSlop;
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 如果到了最底部,而且是上拉操作.那么执行onLoad方法</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">private</span> <span class="keyword">void</span> loadData() {
  
  - <span class="keyword">if</span> (mOnLoadListener != <span class="keyword">null</span>) {
  
  - <span class="comment">// 设置状态</span>
  
  - setLoading(<span class="keyword">true</span>);
  
  - <span class="comment">//</span>
  
  - mOnLoadListener.onLoad();
  
  - }
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * @param loading</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> setLoading(<span class="keyword">boolean</span> loading) {
  
  - isLoading = loading;
  
  - <span class="keyword">if</span> (isLoading) {
  
  - mListView.addFooterView(mListViewFooter);
  
  - } <span class="keyword">else</span> {
  
  - mListView.removeFooterView(mListViewFooter);
  
  - mYDown = <span class="number"></span>;
  
  - mLastY = <span class="number"></span>;
  
  - }
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * @param loadListener</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> setOnLoadListener(OnLoadListener loadListener) {
  
  - mOnLoadListener = loadListener;
  
  - }
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> onScrollStateChanged(AbsListView view, <span class="keyword">int</span> scrollState) {
  
  - 
  - }
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> onScroll(AbsListView view, <span class="keyword">int</span> firstVisibleItem, <span class="keyword">int</span> visibleItemCount,
  
  - <span class="keyword">int</span> totalItemCount) {
  
  - <span class="comment">// 滚动时到了最底部也可以加载更多</span>
  
  - <span class="keyword">if</span> (canLoad()) {
  
  - loadData();
  
  - }
  
  - }
  
  - 
  - <span class="comment">/**</span>
  
  - <span class="comment">     * 加载更多的监听器</span>
  
  - <span class="comment">     * </span>
  
  - <span class="comment">     * @author mrsimple</span>
  
  - <span class="comment">     */</span>
  
  - <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">interface</span> OnLoadListener {
  
  - <span class="keyword">public</span> <span class="keyword">void</span> onLoad();
  
  - }
  
  - }
listview_footer.xml:
**[html]** [view plain](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[copy](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/503362)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/503362/fork)
    <div>
      <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2">
      </embed>
    </div>
  </div>
</div>


  - <span class="tag"><?</span><span class="tag-name">xml</span> <span class="attribute">version</span>=<span class="attribute-value">&#8220;1.0&#8221;</span> <span class="attribute">encoding</span>=<span class="attribute-value">&#8220;utf-8&#8221;</span><span class="tag">?></span>
  
  - <span class="tag"><</span><span class="tag-name">RelativeLayout</span> <span class="attribute">xmlns:android</span>=<span class="attribute-value">&#8220;http://schemas.android.com/apk/res/android&#8221;</span>
  
  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;fill_parent&#8221;</span>
  
  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
  
  - <span class="attribute">android:background</span>=<span class="attribute-value">&#8220;@color/umeng_comm_comments_bg&#8221;</span>
  
  - <span class="attribute">android:gravity</span>=<span class="attribute-value">&#8220;center&#8221;</span>
  
  - <span class="attribute">android:paddingBottom</span>=<span class="attribute-value">&#8220;8dip&#8221;</span>
  
  - <span class="attribute">android:paddingTop</span>=<span class="attribute-value">&#8220;5dip&#8221;</span> <span class="tag">></span>
  
  - 
  - <span class="tag"><</span><span class="tag-name">ProgressBar</span>
  
  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/pull_to_refresh_load_progress&#8221;</span>
  
  - <span class="attribute">style</span>=<span class="attribute-value">&#8220;@android:style/Widget.ProgressBar.Small.Inverse&#8221;</span>
  
  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
  
  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
  
  - <span class="attribute">android:layout_centerVertical</span>=<span class="attribute-value">&#8220;true&#8221;</span>
  
  - <span class="attribute">android:layout_centerHorizontal</span>=<span class="attribute-value">&#8220;true&#8221;</span>
  
  - <span class="attribute">android:paddingRight</span>=<span class="attribute-value">&#8220;100dp&#8221;</span>
  
  - <span class="attribute">android:indeterminate</span>=<span class="attribute-value">&#8220;true&#8221;</span> <span class="tag">/></span>
  
  - 
  - <span class="tag"><</span><span class="tag-name">TextView</span>
  
  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/pull_to_refresh_loadmore_text&#8221;</span>
  
  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;fill_parent&#8221;</span>
  
  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
  
  - <span class="attribute">android:layout_gravity</span>=<span class="attribute-value">&#8220;center&#8221;</span>
  
  - <span class="attribute">android:gravity</span>=<span class="attribute-value">&#8220;center&#8221;</span>
  
  - <span class="attribute">android:paddingTop</span>=<span class="attribute-value">&#8220;5dip&#8221;</span>
  
  - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;@string/load&#8221;</span>
  
  - <span class="attribute">android:textAppearance</span>=<span class="attribute-value">&#8220;?android:attr/textAppearanceMedium&#8221;</span>
  
  - <span class="attribute">android:textColor</span>=<span class="attribute-value">&#8220;@android:color/darker_gray&#8221;</span>
  
  - <span class="attribute">android:textSize</span>=<span class="attribute-value">&#8220;14sp&#8221;</span>
  
  - <span class="attribute">android:textStyle</span>=<span class="attribute-value">&#8220;bold&#8221;</span> <span class="tag">/></span>
  
  - 
  - <span class="tag"></</span><span class="tag-name">RelativeLayout</span><span class="tag">></span>

使用示例

refresh.xml布局文件:
**[html]** [view plain](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[copy](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/503362)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/503362/fork)
    <div>
      <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_3">
      </embed>
    </div>
  </div>
</div>


  - <span class="tag"><?</span><span class="tag-name">xml</span> <span class="attribute">version</span>=<span class="attribute-value">&#8220;1.0&#8221;</span> <span class="attribute">encoding</span>=<span class="attribute-value">&#8220;utf-8&#8221;</span><span class="tag">?></span>
  
  - <span class="tag"><</span><span class="tag-name">myview.RefreshLayout</span> <span class="attribute">xmlns:android</span>=<span class="attribute-value">&#8220;http://schemas.android.com/apk/res/android&#8221;</span>
  
  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/swipe_layout&#8221;</span>
  
  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span>
  
  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> <span class="tag">></span>
  
  - 
  - <span class="tag"><</span><span class="tag-name">ListView</span>
  
  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/listview&#8221;</span>
  
  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span>
  
  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> <span class="tag">></span>
  
  - <span class="tag"></</span><span class="tag-name">ListView</span><span class="tag">></span>
  
  - 
  - <span class="tag"></</span><span class="tag-name">myview.RefreshLayout</span><span class="tag">></span>
activity中的使用 :
**[java]** [view plain](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[copy](http://blog.csdn.net/bboyfeiyu/article/details/39935329#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/503362)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/503362/fork)
    <div>
      <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_4">
      </embed>
    </div>
  </div>
</div>


  - <span class="comment">/**</span>
  
  - <span class="comment"> * @author mrsimple</span>
  
  - <span class="comment"> */</span>
  
  - <span class="keyword">public</span> <span class="keyword">class</span> MainActivity <span class="keyword">extends</span> Activity {
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">protected</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {
  
  - <span class="keyword">super</span>.onCreate(savedInstanceState);
  
  - 
  - setContentView(R.layout.refresh);
  
  - 
  - <span class="comment">// 模拟一些数据</span>
  
  - <span class="keyword">final</span> List<String> datas = <span class="keyword">new</span> ArrayList<String>();
  
  - <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>; i < <span class="number">20</span>; i++) {
  
  - datas.add(<span class="string">&#8220;item &#8211; &#8220;</span> + i);
  
  - }
  
  - 
  - <span class="comment">// 构造适配器</span>
  
  - <span class="keyword">final</span> BaseAdapter adapter = <span class="keyword">new</span> ArrayAdapter<String>(<span class="keyword">this</span>,
  
  - android.R.layout.simple_list_item_1,
  
  - datas);
  
  - <span class="comment">// 获取listview实例</span>
  
  - ListView listView = (ListView) findViewById(R.id.listview);
  
  - listView.setAdapter(adapter);
  
  - 
  - <span class="comment">// 获取RefreshLayout实例</span>
  
  - <span class="keyword">final</span> RefreshLayout myRefreshListView = (RefreshLayout)
  
  - findViewById(R.id.swipe_layout);
  
  - 
  - <span class="comment">// 设置下拉刷新时的颜色值,颜色值需要定义在xml中</span>
  
  - myRefreshListView
  
  - .setColorScheme(R.color.umeng_comm_text_topic_light_color,
  
  - R.color.umeng_comm_yellow, R.color.umeng_comm_green,
  
  - R.color.umeng_comm_linked_text);
  
  - <span class="comment">// 设置下拉刷新监听器</span>
  
  - myRefreshListView.setOnRefreshListener(<span class="keyword">new</span> OnRefreshListener() {
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> onRefresh() {
  
  - 
  - Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">&#8220;refresh&#8221;</span>, Toast.LENGTH_SHORT).show();
  
  - 
  - myRefreshListView.postDelayed(<span class="keyword">new</span> Runnable() {
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> run() {
  
  - <span class="comment">// 更新数据</span>
  
  - datas.add(<span class="keyword">new</span> Date().toGMTString());
  
  - adapter.notifyDataSetChanged();
  
  - <span class="comment">// 更新完后调用该方法结束刷新</span>
  
  - myRefreshListView.setRefreshing(<span class="keyword">false</span>);
  
  - }
  
  - }, <span class="number">1000</span>);
  
  - }
  
  - });
  
  - 
  - <span class="comment">// 加载监听器</span>
  
  - myRefreshListView.setOnLoadListener(<span class="keyword">new</span> OnLoadListener() {
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> onLoad() {
  
  - 
  - Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">&#8220;load&#8221;</span>, Toast.LENGTH_SHORT).show();
  
  - 
  - myRefreshListView.postDelayed(<span class="keyword">new</span> Runnable() {
  
  - 
  - <span class="annotation">@Override</span>
  
  - <span class="keyword">public</span> <span class="keyword">void</span> run() {
  
  - datas.add(<span class="keyword">new</span> Date().toGMTString());
  
  - adapter.notifyDataSetChanged();
  
  - <span class="comment">// 加载完后调用该方法</span>
  
  - myRefreshListView.setLoading(<span class="keyword">false</span>);
  
  - }
  
  - }, <span class="number">1500</span>);
  
  - 
  - }
  
  - });
  
  - }
  
  - 
  - }

效果图

![](http://img.blog.csdn.net/20141009181845718)
github链接 : [下拉刷新库](https://github.com/bboyfeiyu/android_my_pull_refresh_view) 。
示例在android_my_pull_demo工程中,进入demo后点击最后一个按钮查看效果即可。注意,在刷新和加载时,需要有一定的延时才能看到效果,这里我们用postDelay来模拟网络请求等延时操作,否则将看不到加载效果。

💬 评论