Android开源项目PullToRefresh下拉刷新功能详解
程序员文章站
2024-03-06 09:27:31
先看看效果图:
开源项地址:https://github.com/chrisbanes/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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Java RMI详细介绍及简单实例