blob: 625040cc1f2754a2d04618d5820f43aab7f67f85 [file] [log] [blame]
/*
* 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.
*
* <p>Assumes parameter {@code RecyclerView} uses {@link GridLayoutManager}.
*
* <p>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;
}
}