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>

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。