开源项地址: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://download.csdn.net/detail/shark0017/8035465

开源项目PullToRefresh详解(一)——PullToRefreshListView的更多相关文章

  1. 开源项目PullToRefresh详解(二)——PullToRefreshGridView

    这里介绍的是PullToRefreshGridView的使用方法,和之前的PullToRefreshListView方法如出一辙,因为这个开源项目模块化很棒,所以很容易实现.等于说我们可以按照之前使用 ...

  2. 开源项目PullToRefresh详解(四)——PullToRefreshListView和ViewPager的结合使用

    其实这个不是什么新东西了,在介绍(一)中我们就知道了PullToRefreshListView的用法,这里只要将其放入到ViewPager中就行啦.ViewPager还是和以往一样的定义和使用,在适配 ...

  3. 开源项目PullToRefresh详解(三)——PullToRefreshScrollView

    和前几篇文章一样,这里还是先设置布局文件,然后找到这个控件.只不过这里要简单很多. 1.布局文件 <?xml version="1.0" encoding="utf ...

  4. 开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用

    这篇其实没啥重要的,主要就算是个总结吧. 一.布局文件 这里实现的是类似于上图的多图选择的效果.关键在于item布局文件的写法.这也就是这个框架奇葩的一点,莫名其妙的要在一个自定义控件里面再放一个自定 ...

  5. 开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter

    上次写到了开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用,其实我们仍旧可以不使用ActionMode的,所以这里就写一个自己扩展的方法. ...

  6. 开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用

    MultiChoiceBaseAdapter是一个可以多选的BaseAdapter,使用的方式相比来说扩展性更强! 使用方式: 1.布局文件 2.写一个类继承MultiChoiceBaseAdapte ...

  7. 开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用

    MulitChoiceNormalArrayAdapter是我自己定义的一个类,其实就是实现了MulitChoiceArrayAdapter,为什么做这个简单的实现类呢,因为这样我们在不用Action ...

  8. 开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用

    MultiChoiceArrayAdapter其实就是可以多选的ArrayAdapter了,ArrayAdpter我们已经很熟悉了.MultiChoiceArrayAdapter这个类是抽象类,所以使 ...

  9. 开源项目MultiChoiceAdapter详解(一)——概要介绍

    项目地址:https://github.com/ManuelPeinado/MultiChoiceAdapter 这个项目主要是提供了一个多选适配器,使用者可以用它来替换传统的适配器,用途还算比较广泛 ...

随机推荐

  1. window下的窗口事件-js

    window.onfocus = function(){ // 窗口获取焦点事件}; window.onblur= function(){ // 窗口失去焦点事件};有弊端,亲测. 所以我还有一个更好 ...

  2. H5的简介

    1.H5的诞生 2.介绍 HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准. HTML5 是 W3C 与 WHATWG 合作的结果. WHATWG 致力于 web 表单和应用 ...

  3. 关于函数getline()(简单注意事项,不懂你怼我!!!)

    关于getline()函数好使但是有毒: 有两种操作需要进行特殊处理: First: #include <iostream>#include <cstring>#include ...

  4. codevs 1795 金字塔 2

    codevs 1795 金字塔 2这个题比完全背包多了一个总数的限制,即一定要选(m+n)个,题中说总重量不超过n,所以至少选择m个重量为0的,然后初始化的时候,都填成重量为0的,然后再一个个地把它们 ...

  5. P3905 道路重建

    P3905 道路重建我一开始想错了,我的是类似kruskal,把毁坏的边从小到大加,并且判断联通性.但是这有一个问题,你可能会多加,就是这条边没用,但是它比较小,你也加上了.居然还有10分,数据也是水 ...

  6. 什么是新生代 GC 和老年代 GC

    GC 经常发生的区域是堆区,堆区还可以细分为新生代.老年代 jvm堆示意图 新生代 一个 Eden 区 两个 Survivor 区 老年代 默认 新生代(Young)与老年代(Old)的比例的值为 1 ...

  7. NUMA导致的MySQL服务器SWAP问题分析与解决方案

    [SWAP产生原理] 先从swap产生的原理来分析,由于linux内存管理比较复杂,下面以问答的方式列了一些重要的点,方便大家理解: 1.swap是如何产生的 swap指的是一个交换分区或文件,主要是 ...

  8. web前端实现本地存储

    当我们在提及web前端本地存储的时候,首先需要介绍一下本地化存储的概念和历史.本地化存储从来不是一个新奇的概念,因为web应用程序一直在追求的就是媲美甚至超越桌面应用程序.但是桌面应用程序一直优于we ...

  9. 笔记本光驱位置装SSD固态硬盘(亲自试验)

    我的笔记本买的早了,2010年的联想Z460,速度有点慢,本来想换台电脑,想想还是算了,没有太大必要.固态硬盘便宜了,于是在原来的光驱位置装了一个256G的SSD固态硬盘,现在的性能能达到刚买来时的1 ...

  10. AIM Tech Round 3 (Div. 1) B. Recover the String 构造

    B. Recover the String 题目连接: http://www.codeforces.com/contest/708/problem/B Description For each str ...