Android开发之RecyclerView的上拉刷新和下拉加载

本文探讨了Android开发中RecyclerView的使用,重点在于实现上拉刷新和下拉加载功能,这对于构建长列表和优化用户体验至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android开发之RecyclerView的上拉刷新和下拉加载

自2015年谷歌开发者大会的召开后,给我们推出了一个新的控件即RecyclerView,它将逐步取代ListView和GriView,对于一些资讯类新闻类的App而言,下拉刷新上拉加载都是不可缺少的功能,那么RecyclerView如何实现上拉刷新和下拉加载呢,经过本人一段时间的研究,终于实现了,下面将代码贴出,还望诸位大神批评指正,灰常感谢♪(^∇^*)

特别注意:
由于本人的Demo中集成了DATABINDINGLIBRARY,即数据绑定库,故使用AS开发的话,需要配置这两步:
1.在项目的build.gradle(非module)中的dependencies下添加配置
classpath "com.android.databinding:dataBinder:1.0-rc1"
2.在module的build.gradle中的添加配置
apply plugin: 'com.android.databinding'

效果图如下:


核心代码如下:
MainActivity
package com.hxht.testrecyclerviewloadmore;

import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import com.hxht.testrecyclerviewloadmore.adapter.MyRecyclerViewAdapter;
import com.hxht.testrecyclerviewloadmore.callback.OnRcvScrollListener;
import com.hxht.testrecyclerviewloadmore.databinding.ActivityMainBinding;
import com.hxht.testrecyclerviewloadmore.domain.HelpClass;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private List<String> list;
    private int index = 1;
    private int page = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initView();

        initData();
    }

    private void initView() {
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    }

    private void initData() {

        HelpClass helpClass = new HelpClass("正在加载、、、");
        binding.setHelpclass(helpClass);

        list = new ArrayList<>();
        list.clear();
        for (int i = 1; i < 201; i++) {
            list.add("测试" + (i < 10 ? "0" + i : i));
        }

        final MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(MainActivity.this, list);
        RecyclerView.LayoutManager manager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
        binding.recycleview.setAdapter(adapter);
        binding.recycleview.setLayoutManager(manager);
        binding.recycleview.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL_LIST));

        int[] colos = new int[]{
                Color.RED,
                Color.YELLOW,
                Color.GREEN,
                Color.BLUE,
                Color.BLACK
        };
        binding.swiperefreshlayout.setColorSchemeColors(colos);

        binding.swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        list.clear();
                        int count = index++;
                        for (int i = 1; i < 201; i++) {
                            list.add("" + count + "次刷新---item" + (i < 10 ? "0" + i : i));
                        }
                        adapter.notifyDataSetChanged();
                        binding.swiperefreshlayout.setRefreshing(false);
                    }
                }, 5000);
            }
        });

        binding.recycleview.setOnScrollListener(new OnRcvScrollListener() {
            @Override
            public void onBottom() {
                super.onBottom();
                Handler handler = new Handler();
                binding.tvLoadMore.setVisibility(View.VISIBLE);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        int currentPage = page++;
                        int position = list.size() ;
                        for (int i = 1; i < 201; i++) {
                            list.add("加载出第" + currentPage + "页的数据" + (i < 10 ? "0" + i : i));
                        }
                        adapter.notifyDataSetChanged();
                        binding.tvLoadMore.setVisibility(View.GONE);
                        binding.recycleview.smoothScrollToPosition(position);
                    }
                }, 3000);
            }
        });
    }
}

MyRecyclerViewAdapter
package com.hxht.testrecyclerviewloadmore.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.hxht.testrecyclerviewloadmore.R;

import java.util.List;

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {

    private Context mContext;
    private List<String> list;

    public MyRecyclerViewAdapter(Context mContext, List<String> list) {
        this.mContext = mContext;
        this.list = list;
    }

    private interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    private OnItemClickListener mOnItemClickListener;

    public OnItemClickListener getmOnItemClickListener() {
        return mOnItemClickListener;
    }

    public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener) {
        this.mOnItemClickListener = mOnItemClickListener;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(mContext, R.layout.activity_rv_item, null);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        holder.tv.setText(list.get(position));
        holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick(v, position);
                }
            }
        });

    }

    @Override
    public int getItemCount() {
        return list.size();
    }


    class MyViewHolder extends RecyclerView.ViewHolder {
        private View view;
        private TextView tv;

        public MyViewHolder(View itemView) {
            super(itemView);
            this.view = itemView;
            this.tv = (TextView) view.findViewById(R.id.tv);
        }
    }
}

OnBottomListener
package com.hxht.testrecyclerviewloadmore.callback;

public interface OnBottomListener {
    void onBottom();
}

OnRecyclerViewScrollListener
package com.hxht.testrecyclerviewloadmore.callback;


import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

public class OnRecyclerViewScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener {

    private String TAG = getClass().getSimpleName();

    public static enum LAYOUT_MANAGER_TYPE {
        LINEAR,
        GRID,
        STAGGERED_GRID
    }

    protected LAYOUT_MANAGER_TYPE layoutManagerType;

    private int[] lastPositions;

    private int lastVisibleItemPosition;

    private int currentScrollState = 0;

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        //  int lastVisibleItemPosition = -1;
        if (layoutManagerType == null) {
            if (layoutManager instanceof LinearLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR;
            } else if (layoutManager instanceof GridLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.GRID;
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID;
            } else {
                throw new RuntimeException(
                        "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");
            }
        }

        switch (layoutManagerType) {
            case LINEAR:
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager)
                        .findLastVisibleItemPosition();
                break;
            case GRID:
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager)
                        .findLastVisibleItemPosition();
                break;
            case STAGGERED_GRID:
                StaggeredGridLayoutManager staggeredGridLayoutManager
                        = (StaggeredGridLayoutManager) layoutManager;
                if (lastPositions == null) {
                    lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];
                }
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
                lastVisibleItemPosition = findMax(lastPositions);
                break;
        }

    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        currentScrollState = newState;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int visibleItemCount = layoutManager.getChildCount();
        int totalItemCount = layoutManager.getItemCount();
        if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE &&
                (lastVisibleItemPosition) >= totalItemCount - 1)) {
            onBottom();
        }
    }


    @Override
    public void onBottom() {}

    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }
}

DividerItemDecoration
package com.hxht.testrecyclerviewloadmore;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Drawable mDivider;

    private int mOrientation;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent) {


        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }

    }


    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView v = new RecyclerView(parent.getContext());
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

HelpClass
package com.hxht.testrecyclerviewloadmore.domain;

public class HelpClass {

    private String tv_name ;

    public HelpClass(String tv_name) {
        this.tv_name = tv_name;
    }

    public String getTv_name() {
        return tv_name;
    }

    public void setTv_name(String tv_name) {
        this.tv_name = tv_name;
    }

    @Override
    public String toString() {
        return "HelpClass{" +
                "tv_name='" + tv_name + '\'' +
                '}';
    }
}

代码已贴出,正所谓取之于社会,回报于社会,还望诸位大神批评指正,不喜勿喷,灰常感谢♪(^∇^*)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值