admin
2024-06-25 55240ee74a7d6e346b001d6e90b0762a7f456c10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package com.lcjian.lib.recyclerview;
 
import android.os.Handler;
import android.os.Looper;
import android.view.View;
 
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
 
public class LoadMoreAdapter extends AdvanceAdapter {
 
    public static final int STATE_DEFAULT = 0;
    public static final int STATE_LOADING = 1;
    public static final int STATE_ERROR = 2;
    public static final int STATE_END = 3;
 
    private boolean mEnabled = true;
 
    private View mLoadingView;
 
    private View mErrorView;
 
    private View mEndView;
 
    private int mState = STATE_DEFAULT;
 
    private OnLoadMoreListener mOnLoadMoreListener;
 
    private final EndlessRecyclerOnScrollListener mOnScrollListener;
 
    private final Handler mHandler;
 
    private final Runnable mStateSetter;
 
    public LoadMoreAdapter(RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter) {
        super(adapter);
        this.mOnScrollListener = new EndlessRecyclerOnScrollListener() {
            @Override
            public void onLoadMore() {
                if (mOnLoadMoreListener != null) {
                    mOnLoadMoreListener.onLoadMore();
                }
            }
        };
        this.mHandler = new Handler(Looper.getMainLooper());
        this.mStateSetter = () -> {
            switch (mState) {
                case STATE_DEFAULT:
                    removeFooter(mLoadingView);
                    removeFooter(mErrorView);
                    removeFooter(mEndView);
                    break;
                case STATE_LOADING:
                    removeFooter(mErrorView);
                    removeFooter(mEndView);
                    addFooter(mLoadingView);
                    break;
                case STATE_ERROR:
                    removeFooter(mLoadingView);
                    removeFooter(mEndView);
                    addFooter(mErrorView);
                    break;
                case STATE_END:
                    removeFooter(mLoadingView);
                    removeFooter(mErrorView);
                    addFooter(mEndView);
                    break;
                default:
                    break;
            }
        };
    }
 
    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        recyclerView.addOnScrollListener(mOnScrollListener);
    }
 
    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        recyclerView.removeOnScrollListener(mOnScrollListener);
    }
 
    public LoadMoreAdapter setLoadingView(View loadingView) {
        if (mLoadingView != null) {
            removeFooter(mLoadingView);
        }
        mLoadingView = loadingView;
        return this;
    }
 
    public LoadMoreAdapter setErrorView(View errorView) {
        if (mErrorView != null) {
            removeFooter(mErrorView);
        }
        mErrorView = errorView;
        return this;
    }
 
    public LoadMoreAdapter setEndView(View endView) {
        if (mEndView != null) {
            removeFooter(mEndView);
        }
        mEndView = endView;
        return this;
    }
 
    public LoadMoreAdapter setEnabled(boolean enabled) {
        mEnabled = enabled;
        return this;
    }
 
    public LoadMoreAdapter setThreshold(int visibleThreshold) {
        mOnScrollListener.setThreshold(visibleThreshold);
        return this;
    }
 
    public LoadMoreAdapter setOnLoadMoreListener(OnLoadMoreListener onLoadmoreListener) {
        this.mOnLoadMoreListener = onLoadmoreListener;
        return this;
    }
 
    public void setState(int state) {
        mState = state;
        mHandler.post(mStateSetter);
    }
 
    public interface OnLoadMoreListener {
        void onLoadMore();
    }
 
    /**
     * Custom Scroll listener for RecyclerView.
     * Based on implementation https://gist.github.com/ssinss/e06f12ef66c51252563e
     */
    private abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
 
        private int mVisibleThreshold = 5; // The minimum amount of items to have below your current scroll position before mLoading more.
 
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            RecyclerViewPositionHelper recyclerViewHelper = RecyclerViewPositionHelper.createHelper(recyclerView);
            int visibleItemCount = recyclerView.getChildCount();
            int totalItemCount = recyclerViewHelper.getItemCount();
            int firstVisibleItem = recyclerViewHelper.findFirstVisibleItemPosition();
 
            if (mEnabled && mState == STATE_DEFAULT && (totalItemCount - visibleItemCount) <= (firstVisibleItem + mVisibleThreshold)) {
                // End has been reached
                // Do something
                onLoadMore();
            }
        }
 
        private void setThreshold(int visibleThreshold) {
            this.mVisibleThreshold = visibleThreshold;
        }
 
        public abstract void onLoadMore();
    }
}