/** * Locate the visible view which has the earliest adapter position. Will skip headers unless they * are the only one visible. * * @param sectionFirstPosition Position of first position of section.. * @param skipHeader Do not include the section header if it has one. * @return View. */ public View getFirstVisibleView(int sectionFirstPosition, boolean skipHeader) { int lookAt = 0; int childCount = mLayoutManager.getChildCount(); View candidate = null; while (true) { if (lookAt >= childCount) { return candidate; } final View view = mLayoutManager.getChildAt(lookAt); LayoutManager.LayoutParams lp = (LayoutManager.LayoutParams) view.getLayoutParams(); if (sectionFirstPosition == lp.getTestedFirstPosition()) { if (!lp.isHeader || !skipHeader) { return view; } else { candidate = view; } } else { // Skipped past section. return candidate; } lookAt += 1; } }
/** * Find the lowest displayed edge of the section. If there is no member found then return the * default edge instead. * * @param sectionFirstPosition Section id, position of first item in the section. * @param lastIndex Index to start looking from. Usually the index of the last attached view in * this section. * @param defaultEdge Default value. * @return Lowest (attached) edge of the section. */ public int getLowestEdge(int sectionFirstPosition, int lastIndex, int defaultEdge) { // Look from end to find children that are the lowest. for (int i = lastIndex; i >= 0; i--) { View child = mLayoutManager.getChildAt(i); LayoutManager.LayoutParams params = (LayoutManager.LayoutParams) child.getLayoutParams(); if (params.getTestedFirstPosition() != sectionFirstPosition) { break; } if (params.isHeader) { continue; } // A more interesting layout would have to do something more here. return mLayoutManager.getDecoratedBottom(child); } return defaultEdge; }
/** * Find the highest displayed edge of the section. If there is no member found then return the * default edge instead. * * @param sectionFirstPosition Section id, position of first item in the section. * @param firstIndex Child index to start looking from. * @param defaultEdge Default value. * @return Top (attached) edge of the section. */ public int getHighestEdge(int sectionFirstPosition, int firstIndex, int defaultEdge) { // Look from start to find children that are the highest. for (int i = firstIndex; i < mLayoutManager.getChildCount(); i++) { View child = mLayoutManager.getChildAt(i); LayoutManager.LayoutParams params = (LayoutManager.LayoutParams) child.getLayoutParams(); if (params.getTestedFirstPosition() != sectionFirstPosition) { break; } if (params.isHeader) { continue; } // A more interesting layout would have to do something more here. return mLayoutManager.getDecoratedTop(child); } return defaultEdge; }
/** * Locate the last view in this section that is completely visible. Will skip headers unless they * are the only one visible. * * @param sectionFirstPosition First position of section being queried. * @return Last completely visible item or null. */ public View getLastCompletelyVisibleView(int sectionFirstPosition) { final int topEdge = mLayoutManager.getClipToPadding() ? mLayoutManager.getPaddingTop() : 0; final int bottomEdge = mLayoutManager.getClipToPadding() ? mLayoutManager.getHeight() - mLayoutManager.getPaddingBottom() : mLayoutManager.getHeight(); int lookAt = mLayoutManager.getChildCount() - 1; View candidate = null; while (true) { if (lookAt < 0) { return candidate; } final View view = mLayoutManager.getChildAt(lookAt); final boolean topInside = mLayoutManager.getDecoratedTop(view) >= topEdge; final boolean bottomInside = mLayoutManager.getDecoratedBottom(view) <= bottomEdge; LayoutManager.LayoutParams lp = (LayoutManager.LayoutParams) view.getLayoutParams(); if (sectionFirstPosition == lp.getTestedFirstPosition()) { if (topInside && bottomInside) { if (!lp.isHeader) { return view; } else { candidate = view; } } } else if (candidate == null) { sectionFirstPosition = lp.getTestedFirstPosition(); continue; } else { return candidate; } lookAt -= 1; } }
/** * Locate the visible view which has the latest adapter position. * * @param sectionFirstPosition Section id. * @return View. */ public View getLastVisibleView(int sectionFirstPosition) { int lookAt = mLayoutManager.getChildCount() - 1; View candidate = null; while (true) { if (lookAt < 0) { return candidate; } View view = mLayoutManager.getChildAt(lookAt); LayoutManager.LayoutParams lp = (LayoutManager.LayoutParams) view.getLayoutParams(); if (sectionFirstPosition == lp.getTestedFirstPosition()) { if (!lp.isHeader) { return view; } else { candidate = view; } } else { // Skipped past section. return candidate; } lookAt -= 1; } }