美文网首页
RecyclerView实现下拉刷新和加载更多

RecyclerView实现下拉刷新和加载更多

作者: 古早味蛋糕 | 来源:发表于2023-01-02 17:01 被阅读0次
    一、介绍

    RecyclerView的滑动事件,特别是下拉刷新和加载更多事件,现在几乎所有的APP显示数据列表时都会用到。今天在此记录一下自定义RecyclerView下拉刷新和加载更多的实现,主要是对滑动事件的监听和处理。

    二、RecyclerView实现下拉刷新和加载更多
    1、RecyclerView的滑动监听事件,监听上下滑动作

    在RecyclerView的OnScrollListener滑动事件监听中有个好用的方法,就是onScrolled(RecyclerView recyclerView, int dx, int dy),其中根据dx的值的正负就可以判断是在左滑还是右滑,而根据dy的值就可以判断是在上滑还是下滑。

    //上滑
     if(dy>0){
     //相应操作代码
    
     }
     //下滑
     else if(dy<0){
     //相应操作代码
    
     }
    
    2、判断是否滑到了列表的顶部或者列表底部
     //是否滑到底部
      if(!recyclerView.canScrollVertically(1)){
          //相应处理操作
    
      }
    
      //是否滑到顶部
      if(!recyclerView.canScrollVertically(-1)){
          //相应处理操作
    
      }
    
    3、在RecyclerView实现自定义

    知道了滑动事件的判断和处理,就可以很轻松得实现下拉刷新和加载更多了。

    public class RefreshRecycleView extends RecyclerView implements RecyclerView.OnTouchListener {
        private Boolean isLoadMore;//加载更多标志
    
        private Boolean isLoadEnd;//加载到最后的标志
    
        private Boolean isLoadStart;//顶部的标志
    
        private Boolean isRefresh;//下拉刷新标志
    
        private IOnScrollListener listener;//事件监听
    
        private float mLastY;//监听移动的位置
    
        public RefreshRecycleView(Context context) {
            this(context,null);
        }
    
        public RefreshRecycleView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs,0);
    
        }
    
        public RefreshRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
    
        }
    
        /**
         * 初始化
         */
        public void init() {
    
            isLoadEnd = false;
    
            isLoadStart = true;
    
            this.addOnScrollListener(new RecyclerView.OnScrollListener() {
    
                @Override
    
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    //SCROLL_STATE_DRAGGING 拖动时  和   SCROLL_STATE_IDLE 当屏幕停止滚动时
                    // SCROLL_STATE_SETTLING 要移动到最后位置时
    
                    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                        loadData();
                    }
    
                }
    
                @Override
    
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
    
                    //上滑
                    if (dy > 0) {
    
                        //是否滑到底部
                        if (!recyclerView.canScrollVertically(1)) {
                            isLoadEnd = true;
                        } else {
                            isLoadEnd = false;
                        }
    
                    } else if (dy < 0) {
    
                        //是否滑到顶部
                        if (!recyclerView.canScrollVertically(-1)) {
                            isLoadStart = true;
                        } else {
                            isLoadStart = false;
                        }
    
                    }
    
                }
    
            });
    
            this.setOnTouchListener(this);
    
        }
    
        /**
         * 加载数据
         */
    
        private void loadData() {
    
            if (isLoadEnd) {
                // 判断是否已加载所有数据
                if (isLoadMore) {//未加载完所有数据,加载数据,并且还原isLoadEnd值为false,重新定位列表底部
    
                    if (getListener() != null) {
                        getListener().onLoadMore();
                    }
    
                } else {//加载完了所有的数据
                    if (getListener() != null) {
                        getListener().onLoaded();
                    }
    
                }
                isLoadEnd = false;
    
            } else if (isLoadStart) {
    
                if (isRefresh) {
                    if (getListener() != null) {
                        getListener().onRefresh();
                    }
    
                    isLoadStart = false;
    
                }
    
            }
    
        }
    
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
    
            if (mLastY == -1) {
                mLastY = motionEvent.getRawY();
            }
    
            switch (motionEvent.getAction()) {
    
                case MotionEvent.ACTION_MOVE:
    
                    final float deltaY = motionEvent.getRawY() - mLastY;
    
                    mLastY = motionEvent.getRawY();
    
                    //向上移动
                    if (deltaY < 0) {
    
                        //是否滑到底部
                        if (!this.canScrollVertically(1)) {
    
                            isLoadEnd = true;
    
                        } else {
    
                            isLoadEnd = false;
    
                        }
    
                    }
    
                    //向下移动
                    else if (deltaY > 0) {
    
                        //是否滑到顶部
                        if (!this.canScrollVertically(-1)) {
    
                            isLoadStart = true;
    
                        } else {
    
                            isLoadStart = false;
    
                        }
    
                    }
    
                    break;
    
                case MotionEvent.ACTION_DOWN:
    
                    mLastY = motionEvent.getRawY();
    
                    break;
    
                default://重置
    
                    mLastY = -1;
    
                    break;
    
            }
    
            return false;
    
        }
    
        //事件监听
        public interface IOnScrollListener {
    
            void onRefresh();
    
            void onLoadMore();
    
            void onLoaded();
    
        }
    
        public IOnScrollListener getListener() {
    
            return listener;
    
        }
    
        //设置事件监听
    
        public void setListener(IOnScrollListener listener) {
    
            this.listener = listener;
    
        }
    
        public Boolean getLoadMore() {
    
            return isLoadMore;
    
        }
    
        //设置是否支持加载更多
    
        public void setLoadMoreEnable(Boolean loadMore) {
    
            isLoadMore = loadMore;
    
        }
    
        public Boolean getRefresh() {
    
            return isRefresh;
    
        }
    
        //设置是否支持下拉刷新
        public void setRefreshEnable(Boolean refresh) {
    
            isRefresh = refresh;
    
        }
    
    }
    
    三、使用RefreshRecycleView实现刷新功能
    1、定义布局

    引用自定义的RefreshRecycleView就可以
    activity_refresh.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".RefreshActivity">
        <com.zyd.screenautosize.RefreshRecycleView
            android:id="@+id/main_recycle_view_data"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    2、定义RecyclerView.Adapter

    这里只是用系统自带的item布局

    public class RefreshRecycleAdapter extends RecyclerView.Adapter<RefreshRecycleAdapter.ViewHolder> {
    
        private List<String> list;
    
        private Context context;
    
        public RefreshRecycleAdapter(Context context, List<String> list) {
    
            this.context = context;
            this.list = list;
    
        }
    
        @Override
    
        public RefreshRecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
    
            RefreshRecycleAdapter.ViewHolder viewHolder = new RefreshRecycleAdapter.ViewHolder(view);
    
            return viewHolder;
    
        }
    
        @Override
    
        public void onBindViewHolder(ViewHolder holder, int position) {
    
            holder.text.setText(list.get(position));
    
            holder.itemView.setTag(position);
    
        }
    
        @Override
    
        public int getItemCount() {
    
            return list.size();
    
        }
    
        class ViewHolder extends RecyclerView.ViewHolder {
    
            private TextView text;
    
            public ViewHolder(View itemView) {
    
                super(itemView);
    
                text = itemView.findViewById(android.R.id.text1);
    
            }
    
        }
    
    }   
    
    3、在Activity中初始化控件以及数据加载
    public class RefreshActivity extends AppCompatActivity implements RefreshRecycleView.IOnScrollListener {
    
        private RefreshRecycleView recycleView;//下拉刷新RecycleView
    
        private List<String> list;//列表
    
        private RefreshRecycleAdapter adapter;//Adapter
    
        private AlertDialog.Builder builder;//提示框
        private Dialog dialogProgress;
    
        private static final int REFRESH_Load = 0;//下拉刷新
    
        private static final int MORE_Load = 1;//加载更多
    
        private Handler handler = new Handler(Looper.myLooper()) {
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
    
                switch (msg.what) {
                    case REFRESH_Load:
    
                        recycleView.setLoadMoreEnable(true);
    
                        if (dialogProgress.isShowing()) {
                            dialogProgress.hide();
                        }
    
                        if (list != null) {
                            list.clear();
                        }
    
                        loadData();
    
                        adapter.notifyDataSetChanged();
    
                        break;
    
                    case MORE_Load:
    
                        recycleView.setLoadMoreEnable(false);
    
                        if (dialogProgress.isShowing()) {
                            dialogProgress.hide();
                        }
    
                        loadData();
    
                        adapter.notifyDataSetChanged();
    
                        break;
    
                }
    
            }
    
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_refresh);
            initView();
        }
    
        public void initView() {
    
            builder = new AlertDialog.Builder(this);
            setDialog(false);
    
            list = new ArrayList<>();
    
            loadData();
    
            recycleView = findViewById(R.id.main_recycle_view_data);
    
            final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(RefreshActivity.this);
    
            recycleView.setLayoutManager(linearLayoutManager);
    
            adapter = new RefreshRecycleAdapter(RefreshActivity.this, list);
    
            recycleView.setAdapter(adapter);
    
            recycleView.setListener(this);
    
            recycleView.setRefreshEnable(true);
    
            recycleView.setLoadMoreEnable(true);
    
        }
    
        /**
         * 设置Dialog
         * @param isShow
         */
        private void setDialog(boolean isShow) {
            builder.setView(R.layout.layout_progress);
            dialogProgress = builder.create();
            dialogProgress.setCanceledOnTouchOutside(false);
            if (isShow) {
                dialogProgress.show();
            } else {
                dialogProgress.dismiss();
            }
        }
    
        /**
         * 加载数据
         */
    
        public void loadData() {
    
            for (int i = 0; i < 10; i++) {
    
                list.add("第" + i +"行");
    
            }
    
        }
    
        @Override
        public void onRefresh() {
    
            if (!dialogProgress.isShowing()) {
                dialogProgress.show();
            }
    
            new Thread() {
    
                @Override
                public void run() {
                    super.run();
    
                    try {
    
                        sleep(3000);
    
                        handler.sendEmptyMessage(REFRESH_Load);
    
                    } catch (InterruptedException e) {
    
                        e.printStackTrace();
    
                    }
    
                }
    
            }.start();
    
        }
    
        @Override
        public void onLoadMore() {
    
            if (!dialogProgress.isShowing()) {
                dialogProgress.show();
            }
    
            new Thread() {
    
                @Override
                public void run() {
                    super.run();
    
                    try {
    
                        sleep(3000);
    
                        handler.sendEmptyMessage(MORE_Load);
    
                    } catch (InterruptedException e) {
    
                        e.printStackTrace();
    
                    }
    
                }
    
            }.start();
    
        }
    
        @Override
        public void onLoaded() {
    
            Toast.makeText(RefreshActivity.this, "Loaded all", Toast.LENGTH_SHORT).show();
    
        }
    
    }
    

    4.效果图如下:


    1.gif

    相关文章

      网友评论

          本文标题:RecyclerView实现下拉刷新和加载更多

          本文链接:https://www.haomeiwen.com/subject/uiuoqdtx.html