android Recyclerview上拉加载更多

本文介绍了一种解决Android RecyclerView上拉加载更多的方法,特别是针对一次性加载所有item的情况。通过自定义监听器并结合触摸事件,实现了稳定可靠的加载更多功能。

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

在项目中使用列表的下拉刷新和上拉加载更多是很常见的功能,下拉刷新我们可以用android自带的SwipeRefreshLayout这个很好解决。但是上拉加载更多就要去找一些框架了,刚开始的时候我找到一个Mugen的github开源框架,但是有个问题,当页面能够一次加载全部item的时候,上拉加载的功能就失效了。
这是因为当界面一次能够加载完全部item的时候,继续往上拉,Recyclerview的滑动监听,中的onScrolled方法只会在页面加载的时候调用一次,只后就不会被调用了,并且dy=0

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

            }

代码如下:

package com.appnews.utils;

import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

/**
 * Created by Administrator on 2017/5/17.
 */

public class LoadMoreForRecyclerView {
    //最后一个显示的item的position
    private int lastVisibleItemPosition;
    //触摸记录之前的触摸位置
    private float oldY;
    //滑动状态
    private int state;
    //滑动时Y轴偏移(大于0表示向上滑动)
    private int offsetY = 0;
    //touch事件中移动的距离(当前触摸的位置-oldY)
    private float moveY;

    /**
     * 构造方法
     * @param recyclerView
     * @param loadMoreListener
     */
    public LoadMoreForRecyclerView(RecyclerView recyclerView, LoadMoreListener loadMoreListener) {
        width(recyclerView, loadMoreListener);
    }

    /**
     *
     * @param recyclerView  recyclerview
     * @param loadMoreListener 回调监听
     */
    public void width(final RecyclerView recyclerView, LoadMoreListener loadMoreListener) {

        mLoadMoreListener = loadMoreListener;
        //线性布局管理
        final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
       //recyclerview设置滑动监听
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //滑动状态
                state = newState;
                //获得最后一个显示的item位置
                lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //记录Y轴偏移量
                offsetY = dy;
            }
        });

        //设置touch监听
        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_MOVE:
                        //计算出移动的距离(小于0表示向上拖动)
                        moveY = motionEvent.getY() - oldY;
                        //记录当前触摸的位置
                        oldY = motionEvent.getY();
                        break;
                    case MotionEvent.ACTION_UP:
                        //如果是拖动或者飞快滑动并且显示的是适配器中最后一条数据
                        if ((state == 1 || state == 2) && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1) {
                            if (offsetY > 0) {//如果偏移量大于0
                                if (mLoadMoreListener != null) {
                                    //回调加载更多监听
                                    mLoadMoreListener.loadListener();
                                }
                            } else if (offsetY == 0) {//如果偏移量一直等于0
                                if ((moveY) < 0) {//手指移动的距离小于0(向上拖动recyclerView)
                                    if (mLoadMoreListener != null) {
                                        //回调加载更多
                                        mLoadMoreListener.loadListener();
                                    }
                                }
                            }
                        }

                        break;
                }
                //返回值要为false,不会拦截滑动事件
                return false;
            }
        });
    }

    private LoadMoreListener mLoadMoreListener;
    /**
     * 回调接口
     */
    public interface LoadMoreListener {
        void loadListener();
    }
}

使用的时候:

//上拉加载更多滑动监听
        new LoadMoreForRecyclerView(rc, new LoadMoreForRecyclerView.LoadMoreListener() {
            @Override
            public void loadListener() {
                showToast("开始加载");
                getData(2);
            }
        });

rc就是recyclerview,在重写的方法中,进行数据处理。

效果图:
Recyclerview上拉加载更多
如果去研究SwipeRefreshLayout的源码,应该可以实现差不多的效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值