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 int LAYOUT_START = -1;
28 
29     static final int LAYOUT_END = 1;
30 
31     static final int INVALID_LAYOUT = Integer.MIN_VALUE;
32 
33     static final int ITEM_DIRECTION_HEAD = -1;
34 
35     static final int ITEM_DIRECTION_TAIL = 1;
36 
37     /**
38      * We may not want to recycle children in some cases (e.g. layout)
39      */
40     boolean mRecycle = true;
41 
42     /**
43      * Number of pixels that we should fill, in the layout direction.
44      */
45     int mAvailable;
46 
47     /**
48      * Current position on the adapter to get the next item.
49      */
50     int mCurrentPosition;
51 
52     /**
53      * Defines the direction in which the data adapter is traversed.
54      * Should be {@link #ITEM_DIRECTION_HEAD} or {@link #ITEM_DIRECTION_TAIL}
55      */
56     int mItemDirection;
57 
58     /**
59      * Defines the direction in which the layout is filled.
60      * Should be {@link #LAYOUT_START} or {@link #LAYOUT_END}
61      */
62     int mLayoutDirection;
63 
64     /**
65      * This is the target pixel closest to the start of the layout that we are trying to fill
66      */
67     int mStartLine = 0;
68 
69     /**
70      * This is the target pixel closest to the end of the layout that we are trying to fill
71      */
72     int mEndLine = 0;
73 
74     /**
75      * If true, layout should stop if a focusable view is added
76      */
77     boolean mStopInFocusable;
78 
79     /**
80      * If the content is not wrapped with any value
81      */
82     boolean mInfinite;
83 
84     /**
85      * @return true if there are more items in the data adapter
86      */
hasMore(RecyclerView.State state)87     boolean hasMore(RecyclerView.State state) {
88         return mCurrentPosition >= 0 && mCurrentPosition < state.getItemCount();
89     }
90 
91     /**
92      * Gets the view for the next element that we should render.
93      * Also updates current item index to the next item, based on {@link #mItemDirection}
94      *
95      * @return The next element that we should render.
96      */
next(RecyclerView.Recycler recycler)97     View next(RecyclerView.Recycler recycler) {
98         final View view = recycler.getViewForPosition(mCurrentPosition);
99         mCurrentPosition += mItemDirection;
100         return view;
101     }
102 
103     @Override
toString()104     public String toString() {
105         return "LayoutState{"
106                 + "mAvailable=" + mAvailable
107                 + ", mCurrentPosition=" + mCurrentPosition
108                 + ", mItemDirection=" + mItemDirection
109                 + ", mLayoutDirection=" + mLayoutDirection
110                 + ", mStartLine=" + mStartLine
111                 + ", mEndLine=" + mEndLine
112                 + '}';
113     }
114 }
115