开源项地址: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 addingHeader 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 onlytakes 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>开始编写代码
/** * 设置下拉刷新的listview的动作 */ private void initPTRListView() { mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list); //设置拉动监听器 mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {@Overridepublic void onRefresh(PullToRefreshBase<ListView> refreshView) {//设置下拉时显示的日期和时间String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);// 更新显示的labelrefreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);// 开始执行异步任务,传入适配器来进行数据改变new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();} }); // 添加滑动到底部的监听器 mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {@Overridepublic 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); }
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中的全部代码
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>() {@Overridepublic void onRefresh(PullToRefreshBase<ListView> refreshView) {//设置下拉时显示的日期和时间String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);// 更新显示的labelrefreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);// 开始执行异步任务,传入适配器来进行数据改变new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();} }); // 添加滑动到底部的监听器 mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {@Overridepublic 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