1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.recyclerview.widget;
18 
19 import android.view.View;
20 
21 /**
22  * Helper class that keeps temporary state while {LayoutManager} is filling out the empty
23  * space.
24  */
25 class LayoutState {
26 
27     static final String TAG = "LayoutState";
28 
29     static final int LAYOUT_START = -1;
30 
31     static final int LAYOUT_END = 1;
32 
33     static final int INVALID_LAYOUT = Integer.MIN_VALUE;
34 
35     static final int ITEM_DIRECTION_HEAD = -1;
36 
37     static final int ITEM_DIRECTION_TAIL = 1;
38 
39     /**
40      * We may not want to recycle children in some cases (e.g. layout)
41      */
42     boolean mRecycle = true;
43 
44     /**
45      * Number of pixels that we should fill, in the layout direction.
46      */
47     int mAvailable;
48 
49     /**
50      * Current position on the adapter to get the next item.
51      */
52     int mCurrentPosition;
53 
54     /**
55      * Defines the direction in which the data adapter is traversed.
56      * Should be {@link #ITEM_DIRECTION_HEAD} or {@link #ITEM_DIRECTION_TAIL}
57      */
58     int mItemDirection;
59 
60     /**
61      * Defines the direction in which the layout is filled.
62      * Should be {@link #LAYOUT_START} or {@link #LAYOUT_END}
63      */
64     int mLayoutDirection;
65 
66     /**
67      * This is the target pixel closest to the start of the layout that we are trying to fill
68      */
69     int mStartLine = 0;
70 
71     /**
72      * This is the target pixel closest to the end of the layout that we are trying to fill
73      */
74     int mEndLine = 0;
75 
76     /**
77      * If true, layout should stop if a focusable view is added
78      */
79     boolean mStopInFocusable;
80 
81     /**
82      * If the content is not wrapped with any value
83      */
84     boolean mInfinite;
85 
86     /**
87      * @return true if there are more items in the data adapter
88      */
hasMore(RecyclerView.State state)89     boolean hasMore(RecyclerView.State state) {
90         return mCurrentPosition >= 0 && mCurrentPosition < state.getItemCount();
91     }
92 
93     /**
94      * Gets the view for the next element that we should render.
95      * Also updates current item index to the next item, based on {@link #mItemDirection}
96      *
97      * @return The next element that we should render.
98      */
next(RecyclerView.Recycler recycler)99     View next(RecyclerView.Recycler recycler) {
100         final View view = recycler.getViewForPosition(mCurrentPosition);
101         mCurrentPosition += mItemDirection;
102         return view;
103     }
104 
105     @Override
toString()106     public String toString() {
107         return "LayoutState{"
108                 + "mAvailable=" + mAvailable
109                 + ", mCurrentPosition=" + mCurrentPosition
110                 + ", mItemDirection=" + mItemDirection
111                 + ", mLayoutDirection=" + mLayoutDirection
112                 + ", mStartLine=" + mStartLine
113                 + ", mEndLine=" + mEndLine
114                 + '}';
115     }
116 }
117