android 下拉刷新/上拉加载更多【pull-to-refresh】

这两天在做一个功能,需要用到“下拉刷新和上拉加载更多”这样的功能,开始的时候以为都是自己用控件加以控件来完成的,后来,在网上找了好长时间,发现直接可以用别人的现在的 library . 引用别人的library后直接就可以用的,只是注意一些细节就可以了。 我用的是pull to refresh (很多人都说这个比较好点)。

它支持多种常用的需要刷新的View类型,如:ListView、ExpandableListView、GridView、WebView等。这里就给个下载地址吧:https://github.com/chrisbanes/Android-PullToRefresh

用这个来完成一个下拉刷新、上拉加载更多需要解决几个问题:

1.怎样判断用户的操作是下拉还是上拉?

根据下拉和上拉显示的布局的可见状态类区分上拉还是下拉,然后执行相应操作。

在PullToRefresh的类库的com.handmark.pulltorefresh.library包下,打开PullToRefreshBase.java,在这个类的最后面添加如下代码:

public boolean isHeaderShown() {
    return getHeaderLayout().isShown();
}

public boolean isFooterShown() {
    return getFooterLayout().isShown();
}

然后,在刷新事件中的onRefresh中来判断用户的操作是上拉还是下拉。 如下代码 :


if (refreshView.isHeaderShown()) {

Log.i("", "下拉刷新... ");

} else {
	Log.i("", "上拉加载更多... ");
}

2.刷新完成后,怎样让界面恢复到正常显示数据的状态 ?

library提供了相应的方法来结束刷新: mPullRefreshListView.onRefreshComplete();

3.刷新时的提示文本怎样设置 ?

首先说一下刷新的3种情况及设置:

第一种是向下拉刷新,它的设置是: mPullRefreshListView.setMode(Mode.PULL_FROM_END);

第二种是向上拉刷新,它的设置 是:  mPullRefreshListView.setMode(Mode.PULL_FROM_START);

第三种是两端刷新: 它的设置是: PullRefreshListView.setMode(Mode.BOTH);

设置刷新时的提示文本,这里主要需要注意的是getLoadingLayoutProxy(boolean b1, boolean b2),特别注意它的两个参数,相具体的理解,就动手试试就明了了。我的设置代码如下 :


// 下拉刷新时的提示文本设置
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setLastUpdatedLabel("下拉刷新");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setPullLabel("");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setRefreshingLabel("正在刷新");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setReleaseLabel("放开以刷新");
		// 上拉加载更多时的提示文本设置
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setLastUpdatedLabel("上拉加载");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setPullLabel("");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setRefreshingLabel("正在加载...");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setReleaseLabel("放开以加载");

4.上拉加载更多时,更新数据之后,怎样让滚动条的位置依然停在上次加载到的位置 ? 

想要回去上次加载到的位置,首先要得到上次加载的位置,android为我们提供了得到当前滚动条位置的方法:

setSelectionFromTop(int position, int y)  -- position 是上一次的位置(List的下标)   y--是距顶部边缘的距离 (可用系统的参数 )

然后,等 到数据加载完毕后, 将滚动条的位置设置为上一次的位置即可。

用方法 :setSelectionFromTop(y, TRIM_MEMORY_BACKGROUND);

解决了上面的问题,一个简单的下拉刷新 和 上拉加载更多就出来了,下面是我的代码 :


public class MainActivity extends Activity {

	private LinkedList<String> mListItems;
	private PullToRefreshListView mPullRefreshListView;
	private ArrayAdapter<String> mAdapter;
	private String[] mStrings = { "1", "2", "3", "4" };
	private ListView lvShow = null;
	private int y = 0; 

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

		mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
		mPullRefreshListView.setMode(Mode.BOTH);
		// 下拉刷新时的提示文本设置
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setLastUpdatedLabel("下拉刷新");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setPullLabel("");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setRefreshingLabel("正在刷新");
		mPullRefreshListView.getLoadingLayoutProxy(true, false).setReleaseLabel("放开以刷新");
		// 上拉加载更多时的提示文本设置
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setLastUpdatedLabel("上拉加载");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setPullLabel("");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setRefreshingLabel("正在加载...");
		mPullRefreshListView.getLoadingLayoutProxy(false, true).setReleaseLabel("放开以加载");
		// 添加 一个下拉刷新事件
		mPullRefreshListView
				.setOnRefreshListener(new OnRefreshListener<ListView>() {

					@Override
					public void onRefresh(
							PullToRefreshBase<ListView> refreshView) {
						if (refreshView.isHeaderShown()) {
							new GetHeaderDataTask().execute();
						} else {
							// 得到上一次滚动条的位置,让加载后的页面停在上一次的位置,便于用户操作
							y = mListItems.size();
							new GetBottomDataTask().execute();

						}
					}
				});
		lvShow = mPullRefreshListView.getRefreshableView();
		mListItems = new LinkedList<String>();
		mListItems.addAll(Arrays.asList(mStrings));
		mAdapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, mListItems);
		lvShow.setAdapter(mAdapter);
	}

	/*
	 * 功能 : 下拉刷新时的事件处理
	 */
	private class GetHeaderDataTask extends AsyncTask<Void, Void, String[]> {

		@Override
		protected String[] doInBackground(Void... params) {
			// Simulates a background job.
			try {
				Thread.sleep(4000);
			} catch (InterruptedException e) {
			}
			return mStrings;
		}

		@Override
		protected void onPostExecute(String[] result) {
			mListItems.addFirst("-3");
			mListItems.addFirst("-4");
			mListItems.addFirst("-5");
			mAdapter.notifyDataSetChanged();
			// 停止刷新
			mPullRefreshListView.onRefreshComplete();
			super.onPostExecute(result);
		}
	}

	/*
	 * 功能: 上拉加载更多时的事件处理
	 */
	private class GetBottomDataTask extends AsyncTask<Void, Void, String[]> {

		@Override
		protected String[] doInBackground(Void... params) {
			// Simulates a background job.
			try {
				Thread.sleep(4000);
			} catch (InterruptedException e) {
			}
			return mStrings;
		}

		@Override
		protected void onPostExecute(String[] result) {
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("5");
			mListItems.add("8");
			mAdapter.notifyDataSetChanged();
			// 停止刷新
			mPullRefreshListView.onRefreshComplete();
			// 设置滚动条的位置 -- 加载更多之后,滚动条的位置应该在上一次划到的位置
			lvShow.setSelectionFromTop(y, TRIM_MEMORY_BACKGROUNP);
			super.onPostExecute(result);
		}
	}
}

XML布局文件:


<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <com.handmark.pulltorefresh.library.PullToRefreshListView
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
      />
</RelativeLayout>
时间: 2024-08-01 21:45:54

android 下拉刷新/上拉加载更多【pull-to-refresh】的相关文章

十分钟实现ListView下拉刷新上滑加载更多

说到ListView下拉刷新几乎每个APP都会用到,所以ListView下拉刷新是很重要的,就像ListView优化一样是你必会的东西. ListView实现下拉刷新如果我们开发人员自己编写相对来说比较费事的,当我们使用第三方库之后我们再来开发这个功能就会省事很多.相比与自己实现可以少编写不少代码,Android-PullToRefresh库可以轻松实现ListView的下拉刷新功能. 要使用Android—PullToRefesh库对ListView实现下拉刷新要经过以下几个步骤: 1.下载A

最新Android ListView 下拉刷新 上滑加载

开发项目过程中基本都会用到listView的下拉刷新和上滑加载更多,之前大家最常用的应该是pull to refresh或它的变种版吧,google官方在最新的android.support.v4包中增加了一个新类SwipeRefreshLayout,地址 这个类的作用就是提供官方的下拉刷新,并且效果相当不错,而上拉加载更多则用我们自定义的listview,也是相当简单. 下拉刷新 简单的介绍下: 首先它是一个viewgroup,但是它只允许有一个子控件,子控件能是任何view,使用的时候,所在

Android下拉刷新库,利用viewdraghelper实现,集成了下拉刷新,底部加载更多,数据初始加载显示loading等功能

项目Github地址:https://github.com/sddyljsx/pulltorefresh Android下拉刷新库,利用viewdraghelper实现. 集成了下拉刷新,底部加载更多,以及刚进入加载数据的loadview.包括了listview与gridview的改写. 效果1: 效果2: 效果3: 效果4: 效果5: 使用说明: imageList=(ListView)findViewById(R.id.image_list); imageAdapter=new ImageA

IOS学习之UiTableView下拉刷新与自动加载更多,百年不变的效果

IOS学习之UiTableView下拉刷新与自动加载更多,百年不变的效果(五) 五一劳动节马上来临,小伙伴有妹有很激动哟,首先祝天下所有的程序猿节日快乐!这个五一对于我来说有点不一样,我的人生从这个五一就转弯了,爱情长跑8年的我结婚了,一会支付宝账号我会公布出去,请自觉打款!谢谢合作. 灯光闪起来: 舞蹈跳起来: 歌曲唱起来: -------------------------------------------------------------------------------------

Android ListView 下拉刷新 点击加载更多

最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例. 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view; import java.util.Date; import com.example.uitest.R; import android.content.Context; import android.uti

支持下拉刷新和上划加载更多的自定义RecyclerView(仿XListView效果)

首先看效果 下拉刷新:        上划加载        在项目更新的过程中,遇到了一个将XListView换成recyclerView的需求,而且更换完之后大体效果不能变,但是对于下拉刷新这样的效果,谷歌给出的解决方案是把RecyclerView放在一个SwipeRefreshLayout中,但是这样其实是拉下一个小圆形控件实现的,和XListView的header效果不同.在网上找了很多的别人代码,都没有实现我想要的效果,于是自己动手写了一个. 具体实现的效果有以下几条 下拉刷新功能:

Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView

在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/details/78781682 ,这里是看了之后,结合自己实际遇到的问题写的. 首先引入包. //下拉框 implementation 'com.android.support:recyclerview-v7:28.0.0-beta01' implementation 'com.scwang.smar

Android如何定制一个下拉刷新,上滑加载更多的容器

前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉刷新和上滑,非常考验对android布局与父子触摸机制的功底,因此参考gitHub上的一个热门的下拉刷新项目 之所以选择他是因为它一个类就完成了所有View的适配,非常的精简强力. 需求 咱对下拉刷新.上滑加载更多的控件,需求如下: 1:下拉刷新,拖动到一定距离,提示文字变成 放手刷新 2:刷新完成

Android 自定义 ListView 上下拉动&ldquo;刷新最新&rdquo;和&ldquo;加载更多&rdquo;歌曲列表

本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码太多,点击此处下载,自己调试一下. 下载 Demo 环境 Windows 2008 R2 64 位 Eclipse ADT V22.6.2,Android 4.4.3 SAMSUNG GT-I9008L,Android OS 2.2.2 测试数据 本演示的歌曲信息,共有 20 条,包括歌手名.歌曲名.时长.缩

android 安卓 listview 支持下拉刷新 上拉加载更多

[1]重写listView import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGrou