Android SwipeRefreshLayout+RecyclerView实现下拉刷新和上拉加载

一、SwipeRefreshLayout简介
SwipeRefreshLayout作为谷歌官方推荐的下拉刷新控件,在实际开发中,经常都会遇到下拉刷新、上拉加载更多的情形。,该控件集成自ViewGroup在support-v4兼容包下。

  • SwipeRefrshLayout常用的几个方法如下:
    isRefreshing():判断当前的状态是否是刷新状态。
    setColorSchemeResources(int… colorResIds):设置下拉进度条的颜色主题,参数为可变参数,并且是资源id,可以设置多种不同的颜色,每转一圈就显示一种颜色。
    setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置监听,需要重写onRefresh()方法,顶部下拉时会调用这个方法,在里面实现请求数据的逻辑,设置下拉进度条消失等等。
    setProgressBackgroundColorSchemeResource(int colorRes):设置下拉进度条的背景颜色,默认白色。
    setRefreshing(boolean refreshing):设置刷新状态,true表示正在刷新,false表示取消刷新。
    使用SwipeRefrshLayout要想达到刷新的目的,首先需要在这个布局里包裹可以滑动的子控件,如ScrollView、ListView、RecyclerView等,并且只能有一个子控件。然后在代码里设置OnRefreshListener设置监听,最后在监听里设置刷新时的数据获取就可以了。
    二、简单示例
    上面是SwipeRefreshLayout主要方法的作用,其实使用起来非常的简单,接下来先通过一个简单示例来学习SwipeRefreshLayout+RecyclerView的使用方法。
    1、在src/main/res/layout/目录下创建activity_main.xml文件,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefreshlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>

从布局文件中看,在SwipeRefreshLayout控件里面加入RecyclerView子元素。
2、在src/main/res/layout/目录下创建上拉加载和RecyclerView中Item布局文件
上拉加载布局文件activity_main_foot.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v4.widget.ContentLoadingProgressBar
        android:id="@+id/pb_progress"
        style="?android:attr/progressBarStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

RecyclerView中Item布局文件activity_main_item.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardElevation="2dp"
    android:layout_margin="5dp">
    <TextView
        android:id="@+id/textItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="45dp"
        android:text="测试1"
        android:gravity="center"/>
</android.support.v7.widget.CardView>

3、创建一个MyViewHolder类继承RecyclerView.ViewHolder,代码如下所示

public class MyViewHolder extends RecyclerView.ViewHolder {
    private TextView textView;

    public MyViewHolder(View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.textItem);
    }
    public void setTextViewText(String text){
        textView.setText(text);
    }
}

4、创建一个上拉加载FootViewHolder类继承 RecyclerView.ViewHolder,代码如下所示:

public class FootViewHolder extends RecyclerView.ViewHolder {
    ContentLoadingProgressBar contentLoadingProgressBar;

    public FootViewHolder(View itemView) {
        super(itemView);
        contentLoadingProgressBar = itemView.findViewById(R.id.pb_progress);
    }
}

5、创建一个MyAdapter适配器类继承RecyclerView.Adapter<RecyclerView.ViewHolder>

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private final static int TYPE_CONTENT = 0;//正常内容
    private final static int TYPE_FOOTER = 1;//加载View
    private OnLoadMoreListener mOnLoadMoreListener;
    private List<Integer> listData = new ArrayList<>();
    private Context context;
    public MyAdapter(Context context,List<Integer> listData , OnLoadMoreListener mOnLoadMoreListener){
        this.context = context;
        this.listData = listData;
        this.mOnLoadMoreListener = mOnLoadMoreListener;
    }
    @Override
    public int getItemViewType(int position) {
        if (position == listData.size() && mOnLoadMoreListener.isAllScreen()) {
            return TYPE_FOOTER;
        }
        return TYPE_CONTENT;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {
            View view = LayoutInflater.from(context).inflate(R.layout.activity_main_foot, parent, false);
            return new FootViewHolder(view);
        } else {
            View view = LayoutInflater.from(context).inflate(R.layout.activity_main_item, parent, false);
            MyViewHolder myViewHolder = new MyViewHolder(view);
            return myViewHolder;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        if (getItemViewType(position) == TYPE_FOOTER) {
        } else {
            MyViewHolder viewHolder = (MyViewHolder) holder;
            viewHolder.setTextViewText("第" + position + "行");
        }
    }


    @Override
    public int getItemCount() {
        return listData.size() + 1;
    }
}

5、定义一个抽象类实现上拉加载,上拉加载其实主要是继承RecyclerView.OnScrollListener,主要是监听RecyclerView滑动事件,判断它是否滑动了最底部,如果滑动最底部还有数据就去加载数据。代码如下所示:

public abstract class OnLoadMoreListener extends RecyclerView.OnScrollListener {
    private int countItem;
    private int lastItem;
    private boolean isScrolled = false;//是否可以滑动
    private boolean isAllScreen = false;//是否充满全屏
    private RecyclerView.LayoutManager layoutManager;

    /**
     * 加载接口
     *
     * @param countItem 总数量
     * @param lastItem  最后显示的position
     */
    protected abstract void onLoading(int countItem, int lastItem);

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        if (newState==SCROLL_STATE_IDLE){
            Log.d("test","SCROLL_STATE_IDLE,空闲");
        }
        else if (newState==SCROLL_STATE_DRAGGING){
            Log.d("test","SCROLL_STATE_DRAGGING,拖拽");
        }
        else if (newState==SCROLL_STATE_SETTLING){
            Log.d("test","SCROLL_STATE_SETTLING,固定");
        }
        else{
            Log.d("test","其它");
        }
        //拖拽或者惯性滑动时isScolled设置为true
        if (newState == SCROLL_STATE_DRAGGING || newState == SCROLL_STATE_SETTLING) {
            isScrolled = true;
            isAllScreen =true;
        } else {
            isScrolled = false;
        }

    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
            layoutManager = recyclerView.getLayoutManager();
            countItem = layoutManager.getItemCount();
            lastItem = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
        }
        if (isScrolled && countItem != lastItem && lastItem == countItem - 1) {
            onLoading(countItem, lastItem);
        }
    }

    public boolean isAllScreen(){
        return isAllScreen;
    }
}

6、然后在我们MainActivity.java中去使用,代码如下所示

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "wq892373445";
    private MyAdapter myAdapter;
    private LinearLayoutManager layoutManager;
    private SwipeRefreshLayout refreshLayout;
    private RecyclerView recyclerView;
    private Handler handler;
    private List<Integer> listData = new ArrayList<>();
    private int count = 0;
    private OnLoadMoreListener mOnLoadMoreListener;

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

        init();
    }

    private void init() {
        getData("reset");
        handler = new Handler();
        layoutManager = new LinearLayoutManager(this);
        refreshLayout = findViewById(R.id.swiperefreshlayout);
        recyclerView = findViewById(R.id.recyclerview);

        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        mOnLoadMoreListener=new OnLoadMoreListener() {
            @Override
            protected void onLoading(int countItem, int lastItem) {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        getData("loadMore");
                    }
                }, 3000);
            }
        };
        myAdapter = new MyAdapter(this,listData,mOnLoadMoreListener);
        recyclerView.setAdapter(myAdapter);
        recyclerView.addOnScrollListener(mOnLoadMoreListener);

        //设置下拉时圆圈的颜色(可以尤多种颜色拼成)
        refreshLayout.setColorSchemeResources(android.R.color.holo_blue_light,
                android.R.color.holo_red_light,
                android.R.color.holo_orange_light);
        //设置下拉时圆圈的背景颜色(这里设置成白色)
        refreshLayout.setProgressBackgroundColorSchemeResource(android.R.color.white);

        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                getData("refresh");
            }
        });
    }
    private void getData(final String type) {
        if ("reset".equals(type)) {
            listData.clear();
            count = 0;
            for (int i = 0; i < 3; i++) {
                count += 1;
                listData.add(count);
            }
        }
       else if ("refresh".equals(type)) {
            listData.clear();
            count = 0;
            for (int i = 0; i < 13; i++) {
                count += 1;
                listData.add(count);
            }
            myAdapter.notifyDataSetChanged();
            if (refreshLayout.isRefreshing()) {
                refreshLayout.setRefreshing(false);
            }
            Toast.makeText(getApplicationContext(), "刷新完毕", Toast.LENGTH_SHORT).show();
        } else {
            for (int i = 0; i < 3; i++) {
                count += 1;
                listData.add(count);
            }
            myAdapter.notifyDataSetChanged();
            if (refreshLayout.isRefreshing()) {
                refreshLayout.setRefreshing(false);
            }
            Toast.makeText(getApplicationContext(), "加载完毕", Toast.LENGTH_SHORT).show();
        }


    }
}

上述代码首先获取布局控件,先设置RecyclerView显示的管理器和适配器,然后再设置SwipeRefreshLayout。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值