Android’s RecyclerView LayoutManager’s Find By Visibility Methods

Kevin Coughlin
2 min readMar 26, 2015

Got bit by this today so I figured I’d share the knowledge. If you are trying to get a first, last, or completely visible item position from Android’s new RecyclerView LinearLayoutManager using their corresponding method be aware that it can return -1. If no views are laid out that satisfy LinearLayoutManager’s visibility requirement then it will return the static int NO_POSITION value of -1. The method declaration reads:

public static final int NO_POSITION = -1;.../**
* Returns the adapter position of the first visible view.
* <p>
* Note that, this value is not affected by layout orientation or item order traversal.
* ({
@link #setReverseLayout(boolean)}). Views are sorted by their positions in the adapter,
* not in the layout.
* <p>
* If RecyclerView has item decorators, they will be considered in calculations as well.
* <p>
* LayoutManager may pre-cache some views that are not necessarily visible. Those views
* are ignored in this method.
*
*
@return The adapter position of the first visible item or {@link RecyclerView#NO_POSITION} if
* there aren't any visible items.
*
@see #findFirstCompletelyVisibleItemPosition()
*
@see #findLastVisibleItemPosition()
*/
public int findFirstVisibleItemPosition() {
final View child = findOneVisibleChild(0, getChildCount(), false);
return child == null ? NO_POSITION : getPosition(child);
}

If you then attempt to grab the value from your adapter by position you’ll undoubtedly run into an ArrayIndexOutOfBoundsException. I’m not advocating manipulating / restoring RecyclerView state manually (as an example). But if you such a thing is necessary, make sure to make the position calls after your RecyclerView has laid out or be defensive with your array access.

--

--