Android开源项目PullToRefresh下拉刷新功能详解

先看看效果图:

开源项地址:https://github.com/chrisbanes/Android-PullToRefresh

下拉刷新这个功能我们都比较常见了,今天介绍的就是这个功能的实现。我将按照这个开源库的范例来一点一点介绍,今天是介绍比较常见的PullToRefreshListView,是让listView有下拉刷新功能。

1.下载项目包,将library包导入即可,其他的包暂时不用

2.分析源码,看我们可以设置的有哪些

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <declare-styleable name="PullToRefresh">

 <!-- A drawable to use as the background of the Refreshable View -->
 <!-- 设置刷新view的背景 -->
 <attr name="ptrRefreshableViewBackground" format="reference|color" />

 <!-- A drawable to use as the background of the Header and Footer Loading Views -->
 <!-- 设置头部view的背景 -->
 <attr name="ptrHeaderBackground" format="reference|color" />

 <!-- Text Color of the Header and Footer Loading Views -->
 <!-- 设置头部/底部文字的颜色 -->
 <attr name="ptrHeaderTextColor" format="reference|color" />

 <!-- Text Color of the Header and Footer Loading Views Sub Header -->
 <!-- 设置头部/底部副标题的文字颜色 -->
 <attr name="ptrHeaderSubTextColor" format="reference|color" />

 <!-- Mode of Pull-to-Refresh that should be used -->
 <!-- 设置下拉刷新的模式,有多重方式可选。无刷新功能,从顶部刷新,从底部刷新,二者都有,只允许手动刷新 -->
 <attr name="ptrMode">
  <flag name="disabled" value="0x0" />
  <flag name="pullFromStart" value="0x1" />
  <flag name="pullFromEnd" value="0x2" />
  <flag name="both" value="0x3" />
  <flag name="manualOnly" value="0x4" />

  <!-- These last two are depreacted -->
  <!-- 这两个属性不推荐了,用上面的代替即可 -->
  <flag name="pullDownFromTop" value="0x1" />
  <flag name="pullUpFromBottom" value="0x2" />
 </attr>

 <!-- Whether the Indicator overlay(s) should be used -->
 <!-- 是否显示指示箭头 -->
 <attr name="ptrShowIndicator" format="reference|boolean" />

 <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
 <!-- 指示箭头的图片 -->
 <attr name="ptrDrawable" format="reference" />

 <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
 <!-- 顶部指示箭头的图片,设置后会覆盖ptrDrawable中顶部的设置 -->
 <attr name="ptrDrawableStart" format="reference" />

 <!-- Drawable to use as Loading Indicator in the Fooer View. Overrides value set in ptrDrawable. -->
 <!-- 底部指示箭头的图片,设置后会覆盖ptrDrawable中底部的设置 -->
 <attr name="ptrDrawableEnd" format="reference" />

 <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. -->
 <attr name="ptrOverScroll" format="reference|boolean" />

 <!-- Base text color, typeface, size, and style for Header and Footer Loading Views -->
 <!-- 设置文字的基本字体 -->
 <attr name="ptrHeaderTextAppearance" format="reference" />

 <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header -->
 <!-- 设置副标题的基本字体 -->
 <attr name="ptrSubHeaderTextAppearance" format="reference" />

 <!-- Style of Animation should be used displayed when pulling. -->
 <!-- 设置下拉时标识图的动画,默认为rotate -->
 <attr name="ptrAnimationStyle">
  <flag name="rotate" value="0x0" />
  <flag name="flip" value="0x1" />
 </attr>

 <!-- Whether the user can scroll while the View is Refreshing -->
 <!-- 设置刷新时是否允许滚动,一般为true -->
 <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" />

 <!--
  Whether PullToRefreshListView has it's extras enabled. This allows the user to be
  able to scroll while refreshing, and behaves better. It acheives this by adding
  Header and/or Footer Views to the ListView.
 -->
 <!-- 允许在listview中添加头/尾视图 -->
 <attr name="ptrListViewExtrasEnabled" format="reference|boolean" />

 <!--
  Whether the Drawable should be continually rotated as you pull. This only
  takes effect when using the 'Rotate' Animation Style.
 -->
 <!-- 当设置rotate时,可以用这个来设置刷新时旋转的图片 -->
 <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" />

 <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. -->
 <attr name="ptrAdapterViewBackground" format="reference|color" />
 <attr name="ptrDrawableTop" format="reference" />
 <attr name="ptrDrawableBottom" format="reference" />
 </declare-styleable>

</resources>

看到有这么多可以设置的属性,别以为真的就可以定制了。真正要定制还得到layout中改变刷新布局

3.开始用它建立自己的工程
 设置布局文件
 就是插入PullToRefreshListView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="${relativePackage}.${activityClass}"
 android:background="#000000">

<!-- The PullToRefreshListView replaces a standard ListView widget. -->

 <com.handmark.pulltorefresh.library.PullToRefreshListView
 xmlns:ptr="http://schemas.android.com/apk/res-auto"
 android:id="@+id/pull_refresh_list"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:cacheColorHint="#000000"
 android:divider="#19000000"
 android:dividerHeight="4dp"
 android:fadingEdge="none"
 android:fastScrollEnabled="false"
 android:footerDividersEnabled="false"
 android:headerDividersEnabled="false"
 android:smoothScrollbar="true"
 ptr:ptrAnimationStyle="rotate"
 ptr:ptrHeaderTextColor="#ffffff"
 ptr:ptrHeaderSubTextColor="#00ffff"
 ptr:ptrHeaderBackground="@null"
 ptr:ptrDrawable="@drawable/ic_launcher"/>

</RelativeLayout>

开始编写代码

1.找到这个控件,并且设置监听器

这里面用到了一个日期的工具类,其实就是设置上次下拉的时间的。此外在下拉后会触发一个异步任务

 /**
 * 设置下拉刷新的listview的动作
 */
 private void initPTRListView() {
 mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
 //设置拉动监听器
 mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {

  @Override
  public void onRefresh(PullToRefreshBase<ListView> refreshView) {
  //设置下拉时显示的日期和时间
  String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
   DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);

  // 更新显示的label
  refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
  // 开始执行异步任务,传入适配器来进行数据改变
  new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();
  }
 });

 // 添加滑动到底部的监听器
 mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {

  @Override
  public void onLastItemVisible() {
  Toast.makeText(getApplication(), "已经到底了", Toast.LENGTH_SHORT).show();
  }
 });

 //mPullRefreshListView.isScrollingWhileRefreshingEnabled();//看刷新时是否允许滑动
 //在刷新时允许继续滑动
 mPullRefreshListView.setScrollingWhileRefreshingEnabled(true);
 //mPullRefreshListView.getMode();//得到模式
 //上下都可以刷新的模式。这里有两个选择:Mode.PULL_FROM_START,Mode.BOTH,PULL_FROM_END
 mPullRefreshListView.setMode(Mode.BOTH);

 /**
  * 设置反馈音效
  */
 SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
 soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);
 soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);
 soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);
 mPullRefreshListView.setOnPullEventListener(soundListener);
 }

2.从上面的那个控件中,得到它包含的listView,并且设置适配器

 //普通的listview对象
 private ListView actualListView;
 //添加一个链表数组,来存放string数组,这样就可以动态增加string数组中的内容了
 private LinkedList<String> mListItems;
 //给listview添加一个普通的适配器
 private ArrayAdapter<String> mAdapter;

这里用到了一个LinkedList的对象,这个是一个类似于ArrayList的链表数组,比较方便在开头和末尾添加String

 /**
 * 设置listview的适配器
 */
 private void initListView() {
 //通过getRefreshableView()来得到一个listview对象
 actualListView = mPullRefreshListView.getRefreshableView();

 String []data = new String[] {"android","ios","wp","java","c++","c#"};
 mListItems = new LinkedList<String>();
 //把string数组中的string添加到链表中
 mListItems.addAll(Arrays.asList(data));

 mAdapter = new ArrayAdapter<>(getApplicationContext(),
  android.R.layout.simple_list_item_1, mListItems);
 actualListView.setAdapter(mAdapter);
 }

3.写一个异步任务,来模仿从网络加载数据

这里要注意的是,加载完后要出发刷新完成和通知适配器改变的方法

package com.kale.ptrlistviewtest;

import java.util.LinkedList;

import android.os.AsyncTask;
import android.widget.ArrayAdapter;

import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;

/**
 * @author:Jack Tony
 * @tips :通过异步任务来加载网络中的数据,进行更新
 * @date :2014-10-14
 */
public class GetDataTask extends AsyncTask<Void, Void, Void>{

 private PullToRefreshListView mPullRefreshListView;
 private ArrayAdapter<String> mAdapter;
 private LinkedList<String> mListItems;

 public GetDataTask(PullToRefreshListView listView,
  ArrayAdapter<String> adapter,LinkedList<String> listItems) {
 // TODO 自动生成的构造函数存根
 mPullRefreshListView = listView;
 mAdapter = adapter;
 mListItems = listItems;
 }

 @Override
 protected Void doInBackground(Void... params) {
 //模拟请求
 try {
  Thread.sleep(2000);
 } catch (InterruptedException e) {
 }
 return null;
 }

 @Override
 protected void onPostExecute(Void result) {
 // TODO 自动生成的方法存根
 super.onPostExecute(result);
 //得到当前的模式
 Mode mode = mPullRefreshListView.getCurrentMode();
 if(mode == Mode.PULL_FROM_START) {
  mListItems.addFirst("这是刷新出来的数据");
 }
 else {
  mListItems.addLast("这是刷新出来的数据");
 }
 // 通知数据改变了
 mAdapter.notifyDataSetChanged();
 // 加载完成后停止刷新
 mPullRefreshListView.onRefreshComplete();

 }

}

贴上acitivty中的全部代码

MainActivity.java

package com.kale.ptrlistviewtest;

import java.util.Arrays;
import java.util.LinkedList;

import android.app.Activity;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnLastItemVisibleListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.extras.SoundPullEventListener;

public class MainActivity extends Activity {

 //一个可以下拉刷新的listView对象
 private PullToRefreshListView mPullRefreshListView;
 //普通的listview对象
 private ListView actualListView;
 //添加一个链表数组,来存放string数组,这样就可以动态增加string数组中的内容了
 private LinkedList<String> mListItems;
 //给listview添加一个普通的适配器
 private ArrayAdapter<String> mAdapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 initView();

 //一打开应用就自动刷新,下面语句可以写到刷新按钮里面
 mPullRefreshListView.setRefreshing(true);
 //new GetDataTask(mPullRefreshListView, mAdapter, mListItems).execute();
 //mPullRefreshListView.setRefreshing(false);

 }

 private void initView() {
 initPTRListView();
 initListView();
 }

 /**
 * 设置下拉刷新的listview的动作
 */
 private void initPTRListView() {
 mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
 //设置拉动监听器
 mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {

  @Override
  public void onRefresh(PullToRefreshBase<ListView> refreshView) {
  //设置下拉时显示的日期和时间
  String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
   DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);

  // 更新显示的label
  refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
  // 开始执行异步任务,传入适配器来进行数据改变
  new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();
  }
 });

 // 添加滑动到底部的监听器
 mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {

  @Override
  public void onLastItemVisible() {
  Toast.makeText(getApplication(), "已经到底了", Toast.LENGTH_SHORT).show();
  }
 });

 //mPullRefreshListView.isScrollingWhileRefreshingEnabled();//看刷新时是否允许滑动
 //在刷新时允许继续滑动
 mPullRefreshListView.setScrollingWhileRefreshingEnabled(true);
 //mPullRefreshListView.getMode();//得到模式
 //上下都可以刷新的模式。这里有两个选择:Mode.PULL_FROM_START,Mode.BOTH,PULL_FROM_END
 mPullRefreshListView.setMode(Mode.BOTH);

 /**
  * 设置反馈音效
  */
 SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
 soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);
 soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);
 soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);
 mPullRefreshListView.setOnPullEventListener(soundListener);
 }

 /**
 * 设置listview的适配器
 */
 private void initListView() {
 //通过getRefreshableView()来得到一个listview对象
 actualListView = mPullRefreshListView.getRefreshableView();

 String []data = new String[] {"android","ios","wp","java","c++","c#"};
 mListItems = new LinkedList<String>();
 //把string数组中的string添加到链表中
 mListItems.addAll(Arrays.asList(data));

 mAdapter = new ArrayAdapter<>(getApplicationContext(),
  android.R.layout.simple_list_item_1, mListItems);
 actualListView.setAdapter(mAdapter);
 }
}

源码下载:http://xiazai.jb51.net/201609/yuanma/AndroidListView(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android中ListView下拉刷新的实现方法

    ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: package net.loonggg.listview; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater;

  • Android下拉刷新ListView——RTPullListView(demo)

    下拉刷新在越来越多的App中使用,已经形成一种默认的用户习惯,遇到列表显示的内容时,用户已经开始习惯性的拉拉.在交互习惯上已经形成定性.之前在我的文章<IOS学习笔记34-EGOTableViewPullRefresh实现下拉刷新>中介绍过如何在IOS上实现下拉刷新的功能.今天主要介绍下在Android上实现下拉刷新的Demo,下拉控件参考自Github上开源项目PullToRefresh,并做简单修改.最终效果如下:                         工程结构如下: 使用过程中

  • 超好看的下拉刷新动画Android代码实现

    最近看到了好多高端.大气.上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画. 首先我们看一下效果如何: 怎么样?是不是很高大上?接下来我们看一下代码: 一.首先我们需要自定义刷新的动态RefreshView(也就是下拉时候的头) 1.初始化头所占用的Dimens private void initiateDimens() { mScreenWidth = mContext.getResources().ge

  • Android下拉刷新官方版

    网上关于下拉刷新的文章也不少,不过都太长了.恰好发现了官方的下拉刷新库,而且效果还是不错的,简洁美观,用得也挺方便. 下面是效果图: 我的好友原来是空的,刷新后多了两个. 使用还是挺方便的,在布局文件中加入SwipeRefreshLayout ,这个就是下拉刷新的布局. 我在SwipeRefreshLayout的里面还加入了一个ListView 因为我主要用下拉刷新更新了listView里面的内容 . 布局文件: <RelativeLayout xmlns:android="http://

  • Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能(附源码)

    最近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在网上直接找一个现成的,可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理想.有些是因为功能不完整或有Bug,有些是因为使用起来太复杂,十全十美的还真没找到.因此我也是放弃了在网上找现成代码的想法,自己花功夫编写了一种非常简单的下拉刷新实现方案,现在拿出来和大家分享一下.相信在阅读完本篇文章之后,大家都可以在自己的项目中一分钟引入下拉刷新功能. 首先讲一下实现原理.这里我们将采取的方案是使用组合View的方式,先自定义一个布局

  • Android RecyclerView实现下拉刷新和上拉加载

    RecyclerView已经出来很久了,许许多多的项目都开始从ListView转战RecyclerView,那么,上拉加载和下拉刷新是一件很有必要的事情. 在ListView上,我们可以通过自己添加addHeadView和addFootView去添加头布局和底部局实现自定义的上拉和下拉,或者使用一些第三方库来简单的集成,例如Android-pulltorefresh或者android-Ultra-Pull-to-Refresh,后者的自定义更强,但需要自己实现上拉加载. 而在下面我们将用两种方式

  • Android自定义下拉刷新上拉加载

    本文实例为大家分享了Android自定义下拉刷新上拉加载的具体实现步骤,供大家参考,具体内容如下 实现的方式是SwipeRefreshLayout + RecyclerView 的VIewType 首先看效果: 总的思路: 布局文件 <android.support.v4.widget.SwipeRefreshLayout android:layout_marginTop="?attr/actionBarSize" android:id="@+id/one_refres

  • Android实现上拉加载更多以及下拉刷新功能(ListView)

    首先为大家介绍Andorid5.0原生下拉刷新简单实现. 先上效果图: 相对于上一个19.1.0版本中的横条效果好看了很多.使用起来也很简单. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" and

  • Android使用RecyclerView实现自定义列表、点击事件以及下拉刷新

    Android使用RecyclerView 1. 什么是RecyclerView RecyclerView 是 Android-support-v7-21 版本中新增的一个 Widgets,官方对于它的介绍则是:RecyclerView 是 ListView 的升级版本,更加先进和灵活. 简单来说就是:RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式.它被作为ListView和GridView控件的继承者,在最新的support-V7版本中提供支持. 2.

  • Android ListView实现上拉加载更多和下拉刷新功能

    本文实例为大家介绍了Android ListView下拉刷新功能的实现方法和功能,供大家参考,具体内容如下 1.ListView优化方式 界面缓存:ViewHolder+convertView 分页加载:上拉刷新 图片缓存 快速滑动ListView禁止刷新 2.效果 3.上拉加载更多原理及实现 当我们手指滑动到listview最后位置的时候,我们触发加载数据的方法.这触发之前我们需要做一些工作,包括: 如何判断滑动到最后? 如何避免重复加载数据? 加载之后如何刷新界面? 1).界面实现AbsLi

随机推荐