1b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing/*
2b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * Copyright (C) 2018 The Android Open Source Project
3b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *
4b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * Licensed under the Apache License, Version 2.0 (the "License");
5b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * you may not use this file except in compliance with the License.
6b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * You may obtain a copy of the License at
7b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *
8b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *      http://www.apache.org/licenses/LICENSE-2.0
9b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *
10b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * Unless required by applicable law or agreed to in writing, software
11b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * distributed under the License is distributed on an "AS IS" BASIS,
12b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * See the License for the specific language governing permissions and
14b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * limitations under the License.
15b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing */
16b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing
17b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxingpackage androidx.car.widget;
18b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.GridLayoutManager;
20ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
21c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxingimport android.view.View;
22b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing
23b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing/**
24b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * Utility class that helps navigating in GridLayoutManager.
25b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *
26b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * <p>Assumes parameter {@code RecyclerView} uses {@link GridLayoutManager}.
27b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing *
28b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing * <p>Assumes the orientation of {@code GridLayoutManager} is vertical.
29b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing */
30b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxingclass GridLayoutManagerUtils {
31b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing    private GridLayoutManagerUtils() {}
32b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing
33b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing    /**
34b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing     * @param parent RecyclerView that uses GridLayoutManager as LayoutManager.
35b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing     * @return number of items in the first row in {@code RecyclerView}.
36b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing     */
37b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing    public static int getFirstRowItemCount(RecyclerView parent) {
38b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        GridLayoutManager manager = (GridLayoutManager) parent.getLayoutManager();
39b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        int itemCount = parent.getAdapter().getItemCount();
40b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        int spanCount = manager.getSpanCount();
41b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing
42b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        int spanSum = 0;
43b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        int pos = 0;
44b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        while (pos < itemCount && spanSum < spanCount) {
45b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing            spanSum += manager.getSpanSizeLookup().getSpanSize(pos);
46b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing            pos += 1;
47b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        }
48b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        // pos will be either the first item in second row, or item count when items not fill
49b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        // the first row.
50b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing        return pos;
51b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing    }
52c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing
53c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    /**
54c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     * Returns the span index of an item.
55c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     */
56c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    public static int getSpanIndex(View item) {
57c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        GridLayoutManager.LayoutParams layoutParams =
58c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                ((GridLayoutManager.LayoutParams) item.getLayoutParams());
59c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        return layoutParams.getSpanIndex();
60c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    }
61c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing
62c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    /**
63c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     * Returns the span size of an item. {@code item} must be already laid out.
64c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     */
65c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    public static int getSpanSize(View item) {
66c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        GridLayoutManager.LayoutParams layoutParams =
67c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                ((GridLayoutManager.LayoutParams) item.getLayoutParams());
68c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        return layoutParams.getSpanSize();
69c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    }
70c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing
71c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    /**
72c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     * Returns the index of the last item that is on the same row as {@code index}.
73c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     *
74c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     * @param index index of child {@code View} in {@code parent}.
75c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     * @param parent {@link RecyclerView} that contains the View {@code index} points to.
76c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing     */
77c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    public static int getLastIndexOnSameRow(int index, RecyclerView parent) {
78c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        int spanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount();
79c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        int spanSum = GridLayoutManagerUtils.getSpanIndex(parent.getChildAt(index));
80c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        for (int i = index; i < parent.getChildCount(); i++) {
81c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing            spanSum += GridLayoutManagerUtils.getSpanSize(parent.getChildAt(i));
82c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing            if (spanSum > spanCount) {
83c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                // We have reached next row.
84c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing
85c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                // Implicit constraint by grid layout manager:
86c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                // Initial spanSum + spanSize would not exceed spanCount, so it's safe to
87c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                // subtract 1.
88c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing                return i - 1;
89c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing            }
90c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        }
91c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        // Still have not reached row end. Assuming the list only scrolls vertically, we are at
92c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        // the last row.
93c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing        return parent.getChildCount() - 1;
94c5bcb56b9b4ae59dd52acf07764a69c8d1216ec0Yao, Yuxing    }
95b4743b4f78bedfff75ebfd5b2d06d254d9a98860Yao, Yuxing}
96