美文网首页
recyclerview 的焦点控制

recyclerview 的焦点控制

作者: 2eb56199844d | 来源:发表于2018-04-03 16:00 被阅读211次

`
public class BaseGridLayoutManager extends GridLayoutManager {
private String TAG = getClass().getSimpleName();
protected NestedScrollingParentLayout nestedScrollingParent;

public BaseGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}


public BaseGridLayoutManager(Context context, int spanCount) {
    super(context, spanCount);
}


public BaseGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
    super(context, spanCount, orientation, reverseLayout);
}


@Override
public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect,
                                             boolean immediate, boolean focusedChildVisible) {
    nestedScrollingParent = this.getNestedScrollingParent(parent);
    if (nestedScrollingParent == null) {
        return super.requestChildRectangleOnScreen(parent, child, rect, immediate,
                focusedChildVisible);
    }

    return requestChildRectangleOnScreenCustom(parent, child, rect, immediate,
            focusedChildVisible);
}


protected boolean requestChildRectangleOnScreenCustom(RecyclerView parent, View child, Rect rect,
                                                      boolean immediate, boolean focusedChildVisible) {
    int[] scrollAmount = getChildRectangleOnScreenScrollAmount(parent, child, rect,
            immediate);
    int dx = scrollAmount[0];
    int dy = scrollAmount[1];

    if (!focusedChildVisible) {
        if (dx != 0 || dy != 0) {

            GridLayoutManager.LayoutParams layoutParams
                    = (GridLayoutManager.LayoutParams) child.getLayoutParams();
            int margin = layoutParams.bottomMargin + layoutParams.topMargin;
            int scrollHeight = child.findFocus().getMeasuredHeight() + margin;
            int offsetVertical = parent.computeVerticalScrollOffset();
            Timber.e(dy + " *滑动* " + scrollHeight + " * " + offsetVertical);
            if (Math.abs(dy) % scrollHeight != 0) {
                if (dy > 0) { //按键向下。列表向上滚动
                    dy = (int) (Math.floor(dy / scrollHeight) + 1) * scrollHeight;
                } else {
                    dy = -(int) (Math.floor(Math.abs(dy) / scrollHeight) + 1) * scrollHeight;
                }
            }
            if (dy < 0) {
                for (int i = 0; i < getSpanCount(); i++) {
                    if (child == findViewByPosition(i)) {
                        nestedScrollingParent.showTop();
                        parent.smoothScrollToPosition(0);
                        break;
                    }
                }
            } else {
                if (offsetVertical < scrollHeight) {
                    nestedScrollingParent.hideTop();
                }
            }

            if (immediate) {
                parent.scrollBy(dx, dy);
            } else {
                parent.smoothScrollBy(dx, dy);
            }
            return true;
        }
    }

    return false;

}


protected int[] getChildRectangleOnScreenScrollAmount(RecyclerView parent, View child,
                                                      Rect rect, boolean immediate) {
    int[] out = new int[2];
    final int parentLeft = getPaddingLeft();
    final int parentTop = getPaddingTop();
    final int parentRight = getWidth() - getPaddingRight();
    final int parentBottom = getHeight() - getPaddingBottom();
    final int childLeft = child.getLeft() + rect.left - child.getScrollX();
    final int childTop = child.getTop() + rect.top - child.getScrollY();
    final int childRight = childLeft + rect.width();
    final int childBottom = childTop + rect.height();

    final int offScreenLeft = Math.min(0, childLeft - parentLeft);
    final int offScreenTop = Math.min(0, childTop - parentTop);
    final int offScreenRight = Math.max(0, childRight - parentRight);
    final int offScreenBottom = Math.max(0, childBottom - parentBottom);

    // Favor the "start" layout direction over the end when bringing one side or the other
    // of a large rect into view. If we decide to bring in end because start is already
    // visible, limit the scroll such that start won't go out of bounds.
    final int dx;
    if (getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL) {
        dx = offScreenRight != 0 ? offScreenRight
                                 : Math.max(offScreenLeft, childRight - parentRight);
    } else {
        dx = offScreenLeft != 0 ? offScreenLeft
                                : Math.min(childLeft - parentLeft, offScreenRight);
    }

    // Favor bringing the top into view over the bottom. If top is already visible and
    // we should scroll to make bottom visible, make sure top does not go out of bounds.
    final int dy = offScreenTop != 0 ? offScreenTop
                                     : Math.min(childTop - parentTop, offScreenBottom);
    out[0] = dx;
    out[1] = dy;
    Timber.e(child.getBottom() + " * " + " * " + parent.computeVerticalScrollExtent());
    if (dy == 0 && !(parent instanceof CZRecyclerView)) {
        if (child.getBottom() >
                parent.computeVerticalScrollExtent() + parent.computeVerticalScrollOffset()) {
            out[1] = child.getBottom() - parent.computeVerticalScrollExtent() -
                    parent.computeVerticalScrollOffset();
        }
    }
    return out;
}


private NestedScrollingParentLayout getNestedScrollingParent(View v) {
    ViewParent p = v.getParent();

    while (p != null) {
        if (p instanceof NestedScrollingParentLayout) {
            return (NestedScrollingParentLayout) p;
        }

        p = p.getParent();
    }

    return null;
}

}
`

相关文章

网友评论

      本文标题:recyclerview 的焦点控制

      本文链接:https://www.haomeiwen.com/subject/mmcchftx.html