PullToRefresh下拉刷新,上拉分页,返回顶部

一、概述:

PullToRefresh是封装好的上拉分页和下拉刷新库,它支持:
ListView,ExpandableListView,GridView,WebView,ScrollView,HorizontalScrollView,ViewPager

二、准备工作:

2.0、Library下载地址:

https://github.com/chrisbanes/Android-PullToRefresh

2.1、导入配置步骤:

1、下载zip压缩包之后,解压,得到几个文件,如下图:
PullToRefresh下拉刷新,上拉分页,返回顶部_第1张图片
2、在Andriod Studio中New Module,导入libary,记得修改名字,做到见名知意,我命名为MyPullToRefreshLibrary。
3、File->Project Structure->app->Dependencies->右上角+ ->Module Dependency->MyPullToRefreshLibrary->ok
4、如果导入成功的话效果如下图:文件夹上有三本小书
PullToRefresh下拉刷新,上拉分页,返回顶部_第2张图片

2.2、PullToRefresh基本用法:

1、在布局文件中添加PullToRefresh控件,此处以PullToRefreshListView为例;
2、在Activity中,设置监听器OnRefreshListener(2)以响应用户上拉和下拉操作;
3、在监听器的onRefresh()(或者onPullDownToRefresh()和onPullUpToRefresh())方法中执行数据刷新操作,可以通过AsyncTask来实现;
4、在AsyncTask中获取到数据后,记得调用onRefreshComplete()方法通知PullToRefresh控件数据已获取完毕,可以结束刷新操作。

三、代码详解:

以下例子摘自我的一个项目,用到PullToRefreshListView并不是MainActivity,而是一个Fragment,在Fragment中返回顶部时候又遇到种种困惑以及解决方案,下面会一一讲述:

Fragment中的代码:

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.util.List;

import king.timeline.com.timeline.Bean.NEWSBean;
import king.timeline.com.timeline.R;
import king.timeline.com.timeline.adapter.NEWSAdapter;
import king.timeline.com.timeline.baseUtils.BaseFragment;

/**
 * A simple {@link Fragment} subclass.
 */
public class NEWSPagerFragment extends BaseFragment implements View.OnClickListener {
    private String newsPath = "http://api.m.mtime.cn/News/NewsList.api?pageIndex=";
    private int page = 1;
    private PullToRefreshListView pRListView;
    private NEWSAdapter adapter;
    private Button btToTop;//用于返回顶部
    private ListView listView;

    public NEWSPagerFragment(Context context) {
        super(context);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_newspager, container, false);
        init(view);
        getJson(1);//默认下载第一页
        return view;
    }

    @Override
    public void onClick(View v) {
//        listView.setSelection(0);//没有特效,直接返回顶部
//        listView.setSelectionAfterHeaderView();
        listView.smoothScrollToPosition(0);//平滑的返回顶部
    }


    /**
     * xutils网络请求get方式下载json字符串
     */
    private void getJson(int page) {
        RequestParams requestParams = new RequestParams(newsPath + page);
        x.http().get(requestParams, new Callback.CommonCallback() {
            @Override
            public void onSuccess(String result) {
                if (!TextUtils.isEmpty(result)) {
                    //解析json字符串
                    adapter.addList(jsonToList(result));
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });
    }

    private void init(View view) {

        //点击按钮返回顶部
        btToTop = (Button) view.findViewById(R.id.bt_to_top);
        btToTop.setOnClickListener(this);

        pRListView = (PullToRefreshListView) view.findViewById(R.id.news_listView);
        //设置刷新的模式(3中常见模式,1种是只能上拉,2是只能加载更多3是既能上拉又能刷新)
        pRListView.setMode(PullToRefreshBase.Mode.BOTH);
        adapter = new NEWSAdapter(getActivity());
        pRListView.setAdapter(adapter);
        //通过PullToRefresh获取其内部封装的listView对象方便设置返回顶部和返回特效
        listView = pRListView.getRefreshableView();
        //给PullToRefreshListView设置监听
        pRListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2() {

            @Override
            public void onPullDownToRefresh(PullToRefreshBase refreshView) {
                //TODO 设置下拉时候的逻辑
                new FinishRefresh().execute();
            }

            @Override
            public void onPullUpToRefresh(PullToRefreshBase refreshView) {
                //TODO 设置上拉时候触发的方法,加载下一页
                page++;
                getJson(page);
                new FinishRefresh().execute();
            }
        });
    }

    /**
     * 用fastJson解析字符串
     *
     * @param s
     * @return
     */
    private List jsonToList(String s) {
        List mList;
        JSONObject object = JSON.parseObject(s);
        JSONArray array = object.getJSONArray("newsList");
        mList = JSONArray.parseArray(array.toString(), NEWSBean.class);
        //Log.e("===", "mList.size()" + mList.size());
        return mList;
    }

    /**
     * 开启异步任务,用于加载刷新
     */
    private class FinishRefresh extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            pRListView.onRefreshComplete();
        }
    }
}

布局文件中的代码:

"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="king.timeline.com.timeline.fragment.NEWSPagerFragment"
    >

    <com.handmark.pulltorefresh.library.PullToRefreshListView
        android:id="@+id/news_listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    

四,代码说明:

1,设置拉动模式有三种:

pRListView.setMode(PullToRefreshBase.Mode.BOTH);//有上下拉
Mode.BOTH:同时支持上拉下拉
Mode.PULL_FROM_START:只支持下拉Pulling Down
Mode.PULL_FROM_END:只支持上拉Pulling Up

2,注册监听:

两个接口:OnRefreshListener和OnRefreshListener2,

  • 如果Mode设置成Mode.BOTH,需要设置刷新Listener为OnRefreshListener2,并实现onPullDownToRefresh()、onPullUpToRefresh()两个方法。
  • 如果Mode设置成Mode.PULL_FROM_START或Mode.PULL_FROM_END,需要设置刷新Listener为OnRefreshListener,同时实现onRefresh()方法。当然也可以设置为OnRefreshListener2,但是Mode.PULL_FROM_START的时候只调用onPullDownToRefresh()方法,Mode.PULL_FROM的时候只调用onPullUpToRefresh()方法.

3,返回置顶:

  1. Button控件在fragment中无法使用onClick方式设置监听,否则会抛出异常,提示找不到onClick指定的方法,具体原因百度了好久,不知所云。那就乖乖使用setOnClickListener呗。
  2. PullToRefresh返回顶部,需要PullToRefreshListView.getRefreshableView()获取其内部封装的listView对象;然后通过ListView.setSelection(0),或者设置返回特效listView.smoothScrollToPosition(0)
  3. 开启异步任务AsyncTask一方面用于多线程加载数据,另外一方面,在上拉下拉中必须调用这个异步任务,不然下拉圆圈一直转转转,不会停止,我尝试着在下拉逻辑中直接插入一行PullToRefreshListView.onRefreshComplete()来取代new FinishRefresh().execute(),结果还是不凑效,还是一直转不停,所以只有开启异步任务的方式停止刷新了。

效果图:
PullToRefresh下拉刷新,上拉分页,返回顶部_第3张图片 PullToRefresh下拉刷新,上拉分页,返回顶部_第4张图片

你可能感兴趣的:(Android)