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