package com.wasu.cs.widget; import android.content.Context; import android.graphics.Rect; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; public class CenterRecyclerView extends RecyclerView { private Context mContext; public CenterRecyclerView(Context context) { super(context); init(context); } public CenterRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public CenterRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { this.mContext = context; } /*@Override public void smoothScrollBy(int dx, int dy) { if (hasFocus()) { if (dx > 0) { int mdx = (int) (dx +mContext.getResources().getDimension(R.dimen.d_10dp)); super.smoothScrollBy(mdx, dy); } else if (dx < 0) { int mdx = (int) (dx - mContext.getResources().getDimension(R.dimen.d_10dp)); super.smoothScrollBy(mdx, dy); } else { Log.d("danxx", "FRV dy--->" + dx); } } // super.smoothScrollBy(dx ,dy); }*/ /** * center scroll * @param child * @param rect * @param immediate * @return */ @Override public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) { 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; final int childTop = child.getTop()-child.getPaddingTop() + rect.top; 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); int centerTop = getHeight() / 2 - child.getHeight() / 2; int centerBottom = getHeight() / 2 + child.getHeight() / 2; int centerLeft = getWidth() / 2 - child.getWidth() / 2; int centerRight = getWidth() / 2 + child.getWidth() / 2; int position = getChildAdapterPosition(child); int childCount = getAdapter().getItemCount(); int dx = 0; if (position == 0 || position == childCount - 1){ // 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. if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) { dx = offScreenRight != 0 ? offScreenRight : Math.max(offScreenLeft, childRight - parentRight); } else { dx = offScreenLeft != 0 ? offScreenLeft : Math.min(childLeft - parentLeft, offScreenRight); } }else { switch (Gravity.CENTER_HORIZONTAL){ case Gravity.CENTER_HORIZONTAL: case Gravity.CENTER: dx = childLeft - centerLeft; break; case Gravity.LEFT: dx = childLeft - parentLeft; break; } } int dy = 0; if (position == 0 || position == childCount - 1){ // 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. dy = offScreenTop != 0 ? offScreenTop : Math.min(childTop - parentTop, offScreenBottom); }else { switch (Gravity.CENTER_VERTICAL){ case Gravity.CENTER_VERTICAL: case Gravity.CENTER: dy = childTop - centerTop; break; } } if (dx != 0 || dy != 0) { if (immediate) { scrollBy(dx, dy); } else { smoothScrollBy(dx, dy); } return true; } return false; } }