欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-03-06 09:27:31
先看看效果图: 开源项地址:https://github.com/chrisbanes/android-pulltorefresh  下拉刷新这个功能...

先看看效果图:

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中改变刷新布局 

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

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

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