importandroid.content.Context;importandroid.content.res.TypedArray;importandroid.graphics.Canvas;importandroid.graphics.Rect;importandroid.graphics.drawable.Drawable;importandroid.support.annotation.IntDef;importandroid.support.v4.view.ViewCompat;importandroid.support.v7.widget.GridLayoutManager;importandroid.support.v7.widget.RecyclerView;importandroid.support.v7.widget.StaggeredGridLayoutManager;importandroid.util.SparseArray;importandroid.util.SparseIntArray;importandroid.view.View;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;#zs#** Created by MAC on 2018/2/5.#fzs#
public class DividerGridItemDecoration extendsRecyclerView.ItemDecoration {private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; //这个就是设置样式的地方(颜色,宽度等等)public static final int GRID_DIVIDER_HORIZONTAL =GridLayoutManager.HORIZONTAL;public static final int GRID_DIVIDER_VERTICAL =GridLayoutManager.VERTICAL;private final SparseIntArray mHorizontalDividerOffsets = newSparseIntArray();private final SparseIntArray mVerticalDividerOffsets = newSparseIntArray();private final SparseArray mTypeDrawableFactories = new SparseArray<>();
@IntDef({
GRID_DIVIDER_HORIZONTAL,
GRID_DIVIDER_VERTICAL
})
@Retention(RetentionPolicy.SOURCE)private @interfaceOrientation {
}
@Orientationprivate intmOrientation;privateDrawable mHorizontalDivider;privateDrawable mVerticalDivider;public DividerGridItemDecoration(Context context, @Orientation intorientation) {
resolveDivider(context);
setOrientation(orientation);
}private voidresolveDivider(Context context) {final TypedArray a =context.obtainStyledAttributes(ATTRS);
mVerticalDivider= mHorizontalDivider = a.getDrawable(0);
a.recycle();
}public void setOrientation(intorientation) {this.mOrientation =orientation;
}public voidsetVerticalDivider(Drawable verticalDivider) {this.mVerticalDivider =verticalDivider;
}public voidsetHorizontalDivider(Drawable horizontalDivider) {this.mHorizontalDivider =horizontalDivider;
}
@Overridepublic voidonDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawHorizontalDividers(c, parent);
drawVerticalDividers(c, parent);
}
@Overridepublic voidgetItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {final int spanCount =getSpanCount(parent);final int childCount =parent.getAdapter().getItemCount();final int adapterPosition =parent.getChildAdapterPosition(view);if (mHorizontalDividerOffsets.indexOfKey(adapterPosition) < 0) {
mHorizontalDividerOffsets.put(adapterPosition, getHorizontalDivider(parent, adapterPosition).getIntrinsicHeight());
}if (mVerticalDividerOffsets.indexOfKey(adapterPosition) < 0) {
mVerticalDividerOffsets.put(adapterPosition, getVerticalDivider(parent, adapterPosition).getIntrinsicHeight());
}
outRect.set(0, 0, mHorizontalDividerOffsets.get(adapterPosition), mVerticalDividerOffsets.get(adapterPosition));if(isLastRow(adapterPosition, spanCount, childCount)) {
outRect.bottom= 0;
}if(isLastColumn(adapterPosition, spanCount, childCount)) {
outRect.right= 0;
}
}private boolean isLastColumn(int position, int spanCount, intchildCount) {if (mOrientation ==GRID_DIVIDER_VERTICAL) {return (position + 1) % spanCount == 0;
}else{int lastColumnCount = childCount %spanCount;
lastColumnCount= lastColumnCount == 0 ?spanCount : lastColumnCount;return position >= childCount -lastColumnCount;
}
}private boolean isLastRow(int position, int spanCount, intchildCount) {if (mOrientation ==GRID_DIVIDER_VERTICAL) {int lastColumnCount = childCount %spanCount;
lastColumnCount= lastColumnCount == 0 ?spanCount : lastColumnCount;return position >= childCount -lastColumnCount;
}else{return (position + 1) % spanCount == 0;
}
}private intgetSpanCount(RecyclerView parent) {
RecyclerView.LayoutManager layoutManager=parent.getLayoutManager();if (layoutManager instanceofGridLayoutManager) {return((GridLayoutManager) layoutManager).getSpanCount();
}else if (layoutManager instanceofStaggeredGridLayoutManager) {return((StaggeredGridLayoutManager) layoutManager).getSpanCount();
}else{throw new UnsupportedOperationException("the GridDividerItemDecoration can only be used in " +
"the RecyclerView which use a GridLayoutManager or StaggeredGridLayoutManager");
}
}public voiddrawVerticalDividers(Canvas c, RecyclerView parent) {final int left =parent.getPaddingLeft();final int right = parent.getWidth() -parent.getPaddingRight();final int childCount =parent.getChildCount();for (int i = 0; i < childCount; i++) {final View child =parent.getChildAt(i);final RecyclerView.LayoutParams params =(RecyclerView.LayoutParams) child.getLayoutParams();final Drawable divider =getVerticalDivider(parent, params.getViewAdapterPosition());final int top = child.getBottom() + params.bottomMargin +Math.round(ViewCompat.getTranslationY(child));final int bottom = top +divider.getIntrinsicHeight();
mVerticalDividerOffsets.put(params.getViewAdapterPosition(), divider.getIntrinsicHeight());
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}public voiddrawHorizontalDividers(Canvas c, RecyclerView parent) {final int top =parent.getPaddingTop();final int bottom = parent.getHeight() -parent.getPaddingBottom();final int childCount =parent.getChildCount();for (int i = 0; i < childCount; i++) {final View child =parent.getChildAt(i);final RecyclerView.LayoutParams params =(RecyclerView.LayoutParams) child.getLayoutParams();final Drawable divider =getHorizontalDivider(parent, params.getViewAdapterPosition());final int left = child.getRight() + params.rightMargin +Math.round(ViewCompat.getTranslationX(child));final int right = left +divider.getIntrinsicHeight();
mHorizontalDividerOffsets.put(params.getViewAdapterPosition(), divider.getIntrinsicHeight());
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}private Drawable getVerticalDivider(RecyclerView parent, intadapterPosition) {
RecyclerView.Adapter adapter=parent.getAdapter();int itemType =adapter.getItemViewType(adapterPosition);
DrawableCreator drawableCreator=mTypeDrawableFactories.get(itemType);if (drawableCreator != null) {returndrawableCreator.createVertical(parent, adapterPosition);
}returnmVerticalDivider;
}private Drawable getHorizontalDivider(RecyclerView parent, intadapterPosition) {
RecyclerView.Adapter adapter=parent.getAdapter();int itemType =adapter.getItemViewType(adapterPosition);
DrawableCreator drawableCreator=mTypeDrawableFactories.get(itemType);if (drawableCreator != null) {returndrawableCreator.createHorizontal(parent, adapterPosition);
}returnmHorizontalDivider;
}public void registerTypeDrawable(intitemType, DrawableCreator drawableCreator) {
mTypeDrawableFactories.put(itemType, drawableCreator);
}public interfaceDrawableCreator {
Drawable createVertical(RecyclerView parent,intadapterPosition);
Drawable createHorizontal(RecyclerView parent,intadapterPosition);
}
}