lmw
2023-03-11 4df5bb59e5fe9f9d140e5610f7772dd8a05a28d4
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
package com.beloo.widget.chipslayoutmanager;
 
import android.util.SparseArray;
import android.view.View;
 
import androidx.recyclerview.widget.RecyclerView;
 
import com.beloo.widget.chipslayoutmanager.layouter.ICanvas;
import com.beloo.widget.chipslayoutmanager.layouter.IStateFactory;
 
import java.util.List;
 
class DisappearingViewsManager implements IDisappearingViewsManager {
 
    private ICanvas canvas;
    private ChildViewsIterable childViews;
    private IStateFactory stateFactory;
 
    /* in pre-layouter drawing we need item count with items will be actually deleted to pre-draw appearing items properly
    * buf value */
    private int deletingItemsOnScreenCount;
 
    DisappearingViewsManager(ICanvas canvas, ChildViewsIterable childViews, IStateFactory stateFactory) {
        this.canvas = canvas;
        this.childViews = childViews;
        this.stateFactory = stateFactory;
    }
 
    class DisappearingViewsContainer {
        private SparseArray<View> backwardViews = new SparseArray<>();
        private SparseArray<View> forwardViews = new SparseArray<>();
 
        int size() {
            return backwardViews.size() + forwardViews.size();
        }
 
        SparseArray<View> getBackwardViews() {
            return backwardViews;
        }
 
        SparseArray<View> getForwardViews() {
            return forwardViews;
        }
    }
 
    /** @return views which moved from screen, but not deleted*/
    @Override
    public DisappearingViewsContainer getDisappearingViews(RecyclerView.Recycler recycler) {
        final List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
        DisappearingViewsContainer container = new DisappearingViewsContainer();
 
        for (RecyclerView.ViewHolder holder : scrapList) {
            final View child = holder.itemView;
            final RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams();
            if (!lp.isItemRemoved()) {
                if (lp.getViewAdapterPosition() < canvas.getMinPositionOnScreen()) {
                    container.backwardViews.put(lp.getViewAdapterPosition(), child);
                } else if (lp.getViewAdapterPosition() > canvas.getMaxPositionOnScreen()) {
                    container.forwardViews.put(lp.getViewAdapterPosition(), child);
                }
            }
        }
 
        return container;
    }
    /** during pre-layout calculate approximate height which will be free after moving items offscreen (removed or moved)
     * @return approximate height of disappearing views. Could be bigger, than accurate value. */
    @Override
    public int calcDisappearingViewsLength(RecyclerView.Recycler recycler) {
        int removedLength = 0;
 
        Integer minStart = Integer.MAX_VALUE;
        Integer maxEnd = Integer.MIN_VALUE;
 
        for (View view : childViews) {
            RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams();
 
            boolean probablyMovedFromScreen = false;
 
            if (!lp.isItemRemoved()) {
                //view won't be removed, but maybe it is moved offscreen
                int pos = lp.getViewLayoutPosition();
 
                pos = recycler.convertPreLayoutPositionToPostLayout(pos);
                probablyMovedFromScreen = pos < canvas.getMinPositionOnScreen() || pos > canvas.getMaxPositionOnScreen();
            }
 
            if (lp.isItemRemoved() || probablyMovedFromScreen) {
                deletingItemsOnScreenCount++;
 
                minStart = Math.min(minStart, stateFactory.getStart(view));
                maxEnd = Math.max(maxEnd, stateFactory.getEnd(view));
            }
        }
 
        if (minStart != Integer.MAX_VALUE) {
            removedLength = maxEnd - minStart;
        }
 
        return removedLength;
    }
 
    @Override
    public int getDeletingItemsOnScreenCount() {
        return deletingItemsOnScreenCount;
    }
 
    @Override
    public void reset() {
        deletingItemsOnScreenCount = 0;
    }
}