Android RecyclerView滑动到底部/上拉/上拉见底自动加载更多实现以及点击/长按事件处理

简介: Android RecyclerView滑动到底部/上拉/上拉见底自动加载更多实现以及点击/长按事件处理Android RecyclerView下拉加载更多有Android谷歌官方的实现,实现的方式是通过SwipeRefreshLayout把RecyclerView包裹起来,然后就可以通过SwipeRefreshLayout的回调接口实现下拉刷新功能。
Android RecyclerView滑动到底部/上拉/上拉见底自动加载更多实现以及点击/长按事件处理


Android RecyclerView下拉加载更多有Android谷歌官方的实现,实现的方式是通过SwipeRefreshLayout把RecyclerView包裹起来,然后就可以通过SwipeRefreshLayout的回调接口实现下拉刷新功能。
Android上拉加载上拉刷新的实现没有官方统一策略,现在我给出一个实现好的工具类:
import android.support.v7.widget.RecyclerView;

/**
 * Created by fly on 2018/3/22.
 */

public class RecyclerViewUtil {
    private boolean enable = true;
    private RecyclerView mRecyclerView;
    private RecyclerViewLoadMoreListener mRecyclerViewLoadMoreListener;

    public RecyclerViewUtil(RecyclerView mRecyclerView) {
        this.mRecyclerView = mRecyclerView;
    }

    public void setRecyclerViewLoadMoreListener(RecyclerViewLoadMoreListener listener) {
        this.mRecyclerViewLoadMoreListener = listener;
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (newState == RecyclerView.SCROLL_STATE_IDLE && isBottom(mRecyclerView)) {
                    if (enable && mRecyclerViewLoadMoreListener != null) {
                        mRecyclerViewLoadMoreListener.onLoadMore();
                    }
                }
            }
        });
    }

    public void setLoadMoreEnable(boolean enable) {
        this.enable = enable;
    }

    private boolean isBottom(RecyclerView recyclerView) {
        if (recyclerView == null)
            return false;

        if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange())
            return true;

        return false;
    }

    public interface RecyclerViewLoadMoreListener {
        public void onLoadMore();
    }
}


使用方式,构造一个RecyclerViewUtil,把RecyclerView传递进去,就可以使用了。如:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private RecyclerViewAdapter mAdapter;
    private ArrayList<String> data;

    private int START_POS = 0;
    private RecyclerViewUtil mRecyclerViewUtil;

    private Random random = new Random();

    private int MAX_COUNT = 20;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        data = new ArrayList<>();
        int count = random.nextInt(MAX_COUNT);
        for (int i = 0; i < count; i++) {
            data.add(String.valueOf(i));
        }

        START_POS = START_POS + count;

        setContentView(R.layout.activity_main);

        RecyclerView mRecyclerView = findViewById(R.id.recycler_view);
        LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLinearLayoutManager);

        mAdapter = new RecyclerViewAdapter();
        mRecyclerView.setAdapter(mAdapter);

        mRecyclerViewUtil = new RecyclerViewUtil(mRecyclerView);
        mRecyclerViewUtil.setRecyclerViewLoadMoreListener(new RecyclerViewUtil.RecyclerViewLoadMoreListener() {
            @Override
            public void onLoadMore() {
                Toast.makeText(getApplicationContext(), "已经到底,加载更多...", Toast.LENGTH_SHORT).show();
                mRecyclerViewUtil.setLoadMoreEnable(false);

                load(START_POS, random.nextInt(MAX_COUNT));
            }
        });
    }

    private void load(int startPos, int count) {
        for (int i = 0; i < count; i++) {
            data.add(startPos + i + "");
        }

        mAdapter.notifyDataSetChanged();
        Toast.makeText(getApplicationContext(), "加载了" + count + " 条数据", Toast.LENGTH_SHORT).show();

        START_POS = startPos + count;
        mRecyclerViewUtil.setLoadMoreEnable(true);
    }

    public class RecyclerViewAdapter extends RecyclerView.Adapter<MyViewHolder> {

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(getApplicationContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.text.setText(data.get(position));
        }

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

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

        public MyViewHolder(View itemView) {
            super(itemView);
            text = itemView.findViewById(android.R.id.text1);
        }
    }
}

另外,Android RecyclerView也没有实现item点击或长按事件的触发,以前我写过一篇文章,实现了该功能,《Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类》链接:https://blog.csdn.net/zhangphil/article/details/53231344 

可以把这两套方案整合在一起,实现一个完整的Android RecyclerView工具包类。整合在一起的新RecyclerViewUtil:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by fly on 2018/3/22.
 */

public class RecyclerViewUtil {
    private boolean enable = true;
    private RecyclerView mRecyclerView;
    private OnLoadMoreListener mOnLoadMoreListener;

    private GestureDetector mGestureDetector = null;
    private RecyclerView.SimpleOnItemTouchListener mSimpleOnItemTouchListener;
    private OnItemClickListener mOnItemClickListener = null;
    private OnItemLongClickListener mOnItemLongClickListener = null;

    public RecyclerViewUtil(Context mContext, RecyclerView recyclerView) {
        this.mRecyclerView = recyclerView;

        mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            //长按事件
            @Override
            public void onLongPress(MotionEvent e) {
                super.onLongPress(e);
                if (mOnItemLongClickListener != null) {
                    View childView = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
                    if (childView != null) {
                        int position = mRecyclerView.getChildLayoutPosition(childView);
                        mOnItemLongClickListener.onItemLongClick(position, childView);
                    }
                }
            }

            //单击事件
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                if (mOnItemClickListener != null) {
                    View childView = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
                    if (childView != null) {
                        int position = mRecyclerView.getChildLayoutPosition(childView);
                        mOnItemClickListener.onItemClick(position, childView);
                        return true;
                    }
                }

                return super.onSingleTapUp(e);
            }
        });

        mSimpleOnItemTouchListener = new RecyclerView.SimpleOnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                if (mGestureDetector.onTouchEvent(e)) {
                    return true;
                }
                return false;
            }
        };

        mRecyclerView.addOnItemTouchListener(mSimpleOnItemTouchListener);
    }

    public void setOnLoadMoreListener(OnLoadMoreListener listener) {
        this.mOnLoadMoreListener = listener;
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (newState == RecyclerView.SCROLL_STATE_IDLE && isBottom(mRecyclerView)) {
                    if (enable && mOnLoadMoreListener != null) {
                        mOnLoadMoreListener.onLoadMore();
                    }
                }
            }
        });
    }

    /**
     * true 打开上拉加载 false,关闭上拉加载
     * @param enable
     */
    public void setLoadMoreEnable(boolean enable) {
        this.enable = enable;
    }

    private boolean isBottom(RecyclerView recyclerView) {
        if (recyclerView == null)
            return false;

        if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange())
            return true;

        return false;
    }

    public interface OnLoadMoreListener {
        public void onLoadMore();
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener listener) {
        mOnItemLongClickListener = listener;
    }

    //长按事件接口
    public interface OnItemLongClickListener {
        public void onItemLongClick(int position, View view);
    }

    //单击事件接口
    public interface OnItemClickListener {
        public void onItemClick(int position, View view);
    }
}

新的RecyclerViewUtil实现了上拉加载更多,单击,长按事件的处理。


使用方式和上一个例子类似:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private RecyclerViewAdapter mAdapter;
    private ArrayList<String> data;

    private int START_POS = 0;
    private RecyclerViewUtil mRecyclerViewUtil;

    private Random random = new Random();

    private int MAX_COUNT = 20;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        data = new ArrayList<>();
        int count = random.nextInt(MAX_COUNT);
        for (int i = 0; i < count; i++) {
            data.add(String.valueOf(i));
        }

        START_POS = START_POS + count;

        setContentView(R.layout.activity_main);

        RecyclerView mRecyclerView = findViewById(R.id.recycler_view);
        LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLinearLayoutManager);

        mAdapter = new RecyclerViewAdapter();
        mRecyclerView.setAdapter(mAdapter);

        mRecyclerViewUtil = new RecyclerViewUtil(this, mRecyclerView);
        mRecyclerViewUtil.setOnLoadMoreListener(new RecyclerViewUtil.OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                Toast.makeText(getApplicationContext(), "已经到底,加载更多...", Toast.LENGTH_SHORT).show();
                mRecyclerViewUtil.setLoadMoreEnable(false);
                load(START_POS, random.nextInt(MAX_COUNT));
            }
        });

        mRecyclerViewUtil.setOnItemClickListener(new RecyclerViewUtil.OnItemClickListener() {
            @Override
            public void onItemClick(int position, View view) {
                Toast.makeText(getApplicationContext(), "单击" + position, Toast.LENGTH_SHORT).show();
            }
        });

        mRecyclerViewUtil.setOnItemLongClickListener(new RecyclerViewUtil.OnItemLongClickListener() {
            @Override
            public void onItemLongClick(int position, View view) {
                Toast.makeText(getApplicationContext(), "长按" + position, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void load(int startPos, int count) {
        for (int i = 0; i < count; i++) {
            data.add(startPos + i + "");
        }

        mAdapter.notifyDataSetChanged();
        Toast.makeText(getApplicationContext(), "加载了" + count + " 条数据", Toast.LENGTH_SHORT).show();

        START_POS = startPos + count;
        mRecyclerViewUtil.setLoadMoreEnable(true);
    }

    public class RecyclerViewAdapter extends RecyclerView.Adapter<MyViewHolder> {

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(getApplicationContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.text.setText(data.get(position));
        }

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

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

        public MyViewHolder(View itemView) {
            super(itemView);
            text = itemView.findViewById(android.R.id.text1);
        }
    }
}


相关文章
|
3月前
|
JavaScript Android开发
使用贝叶斯曲线滑动安卓屏幕(autojsPro7)
使用贝叶斯曲线滑动安卓屏幕(autojsPro7)
60 0
|
3月前
|
API Android开发 开发者
Android UI设计: 什么是RecyclerView?为什么它比ListView更好?
Android UI设计: 什么是RecyclerView?为什么它比ListView更好?
31 2
|
4月前
|
Java Android开发
Android Studio入门之按钮触控的解析及实战(附源码 超详细必看)(包括按钮控件、点击和长按事件、禁用与恢复按钮)
Android Studio入门之按钮触控的解析及实战(附源码 超详细必看)(包括按钮控件、点击和长按事件、禁用与恢复按钮)
159 0
|
7月前
|
缓存 Android开发
Android RecyclerView 实现瀑布流
Android RecyclerView 实现瀑布流
|
7月前
|
Android开发
Android RecyclerView 使用大全 - 基础使用,item 动画,下拉刷新等(三)
Android RecyclerView 使用大全 - 基础使用,item 动画,下拉刷新等
|
16天前
|
XML Java Android开发
Android每点击一次按钮就添加一条数据
Android每点击一次按钮就添加一条数据
21 1
|
3月前
|
Android开发 Kotlin 索引
Android Compose——ScrollableTabRow和LazyColumn同步滑动
Android Compose——ScrollableTabRow和LazyColumn同步滑动
|
3月前
|
Android开发
解决在Android Compose中点击空白处收回软键盘
解决在Android Compose中点击空白处收回软键盘
|
4月前
|
Android开发 Kotlin
android开发,使用kotlin学习滚动控件RecyclerView
android开发,使用kotlin学习滚动控件RecyclerView
36 0
|
4月前
|
XML Java Android开发
Android App手势冲突处理中上下左右滑动的处理以及侧滑边缘菜单的讲解及实战(附源码 可直接使用)
Android App手势冲突处理中上下左右滑动的处理以及侧滑边缘菜单的讲解及实战(附源码 可直接使用)
64 0