package com.lcjian.lib.recyclerview;
|
|
/**
|
* RecyclerView position helper class for any LayoutManager.
|
* <p/>
|
* compile 'com.android.support:recyclerview-v7:22.0.0'
|
*/
|
|
import androidx.recyclerview.widget.OrientationHelper;
|
import androidx.recyclerview.widget.RecyclerView;
|
import android.view.View;
|
|
public class RecyclerViewPositionHelper {
|
|
final RecyclerView recyclerView;
|
final RecyclerView.LayoutManager layoutManager;
|
|
private RecyclerViewPositionHelper(RecyclerView recyclerView) {
|
this.recyclerView = recyclerView;
|
this.layoutManager = recyclerView.getLayoutManager();
|
}
|
|
public static RecyclerViewPositionHelper createHelper(RecyclerView recyclerView) {
|
if (recyclerView == null) {
|
throw new NullPointerException("Recycler View is null");
|
}
|
return new RecyclerViewPositionHelper(recyclerView);
|
}
|
|
/**
|
* Returns the adapter item count.
|
*
|
* @return The total number on items in a layout manager
|
*/
|
public int getItemCount() {
|
return layoutManager == null ? 0 : layoutManager.getItemCount();
|
}
|
|
/**
|
* Returns the adapter position of the first visible view. This position does not include
|
* adapter changes that were dispatched after the last layout pass.
|
*
|
* @return The adapter position of the first visible item or {@link RecyclerView#NO_POSITION} if
|
* there aren't any visible items.
|
*/
|
public int findFirstVisibleItemPosition() {
|
final View child = findOneVisibleChild(0, layoutManager.getChildCount(), false, true);
|
return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child);
|
}
|
|
/**
|
* Returns the adapter position of the first fully visible view. This position does not include
|
* adapter changes that were dispatched after the last layout pass.
|
*
|
* @return The adapter position of the first fully visible item or
|
* {@link RecyclerView#NO_POSITION} if there aren't any visible items.
|
*/
|
public int findFirstCompletelyVisibleItemPosition() {
|
final View child = findOneVisibleChild(0, layoutManager.getChildCount(), true, false);
|
return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child);
|
}
|
|
/**
|
* Returns the adapter position of the last visible view. This position does not include
|
* adapter changes that were dispatched after the last layout pass.
|
*
|
* @return The adapter position of the last visible view or {@link RecyclerView#NO_POSITION} if
|
* there aren't any visible items
|
*/
|
public int findLastVisibleItemPosition() {
|
final View child = findOneVisibleChild(layoutManager.getChildCount() - 1, -1, false, true);
|
return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child);
|
}
|
|
/**
|
* Returns the adapter position of the last fully visible view. This position does not include
|
* adapter changes that were dispatched after the last layout pass.
|
*
|
* @return The adapter position of the last fully visible view or
|
* {@link RecyclerView#NO_POSITION} if there aren't any visible items.
|
*/
|
public int findLastCompletelyVisibleItemPosition() {
|
final View child = findOneVisibleChild(layoutManager.getChildCount() - 1, -1, true, false);
|
return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child);
|
}
|
|
View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) {
|
OrientationHelper helper;
|
if (layoutManager.canScrollVertically()) {
|
helper = OrientationHelper.createVerticalHelper(layoutManager);
|
} else {
|
helper = OrientationHelper.createHorizontalHelper(layoutManager);
|
}
|
|
final int start = helper.getStartAfterPadding();
|
final int end = helper.getEndAfterPadding();
|
final int next = toIndex > fromIndex ? 1 : -1;
|
View partiallyVisible = null;
|
for (int i = fromIndex; i != toIndex; i += next) {
|
final View child = layoutManager.getChildAt(i);
|
final int childStart = helper.getDecoratedStart(child);
|
final int childEnd = helper.getDecoratedEnd(child);
|
if (childStart < end && childEnd > start) {
|
if (completelyVisible) {
|
if (childStart >= start && childEnd <= end) {
|
return child;
|
} else if (acceptPartiallyVisible && partiallyVisible == null) {
|
partiallyVisible = child;
|
}
|
} else {
|
return child;
|
}
|
}
|
}
|
return partiallyVisible;
|
}
|
}
|