`
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;
}
}
`
网友评论