/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package androidx.car.widget; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.view.View; /** * Utility class that helps navigating in GridLayoutManager. * *

Assumes parameter {@code RecyclerView} uses {@link GridLayoutManager}. * *

Assumes the orientation of {@code GridLayoutManager} is vertical. */ class GridLayoutManagerUtils { private GridLayoutManagerUtils() {} /** * @param parent RecyclerView that uses GridLayoutManager as LayoutManager. * @return number of items in the first row in {@code RecyclerView}. */ public static int getFirstRowItemCount(RecyclerView parent) { GridLayoutManager manager = (GridLayoutManager) parent.getLayoutManager(); int itemCount = parent.getAdapter().getItemCount(); int spanCount = manager.getSpanCount(); int spanSum = 0; int pos = 0; while (pos < itemCount && spanSum < spanCount) { spanSum += manager.getSpanSizeLookup().getSpanSize(pos); pos += 1; } // pos will be either the first item in second row, or item count when items not fill // the first row. return pos; } /** * Returns the span index of an item. */ public static int getSpanIndex(View item) { GridLayoutManager.LayoutParams layoutParams = ((GridLayoutManager.LayoutParams) item.getLayoutParams()); return layoutParams.getSpanIndex(); } /** * Returns the span size of an item. {@code item} must be already laid out. */ public static int getSpanSize(View item) { GridLayoutManager.LayoutParams layoutParams = ((GridLayoutManager.LayoutParams) item.getLayoutParams()); return layoutParams.getSpanSize(); } /** * Returns the index of the last item that is on the same row as {@code index}. * * @param index index of child {@code View} in {@code parent}. * @param parent {@link RecyclerView} that contains the View {@code index} points to. */ public static int getLastIndexOnSameRow(int index, RecyclerView parent) { int spanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount(); int spanSum = GridLayoutManagerUtils.getSpanIndex(parent.getChildAt(index)); for (int i = index; i < parent.getChildCount(); i++) { spanSum += GridLayoutManagerUtils.getSpanSize(parent.getChildAt(i)); if (spanSum > spanCount) { // We have reached next row. // Implicit constraint by grid layout manager: // Initial spanSum + spanSize would not exceed spanCount, so it's safe to // subtract 1. return i - 1; } } // Still have not reached row end. Assuming the list only scrolls vertically, we are at // the last row. return parent.getChildCount() - 1; } }