RecyclerView结构布局:线性、网格、瀑布流,其中最常用的就是线性和网格布局。
设置线性列表Item分割线一般比较容易,可以通过两种方案来做:
- 直接布局item的时候,把要作为分割线的线条或者其他形式的,直接添加在item布局中。并且可以动态控制分割线的显示与否。
- 通过RecyclerView.ItemDecoration来设置,无非就是设置左、右、上、下间隔
public class RecyclerLinearSpaceItemDecoration extends RecyclerView.ItemDecoration { int mSpace; int type; //线性横向:左间距 private final int HORIZONTAL_LEFT = 1; //线性横向:右间距 private final int HORIZONTAL_RIGHT = 2; //线性纵向:top间距 private final int VERTICAL_TOP = 3; //线性纵向:bottom间距 private final int VERTICAL_BOTTOM = 4; /** * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies * the number of pixels that the item view should be inset by, similar to padding or margin. * The default implementation sets the bounds of outRect to 0 and returns. * <p> * <p> * If this ItemDecoration does not affect the positioning of item views, it should set * all four fields of <code>outRect</code> (left, top, right, bottom) to zero * before returning. * <p> * <p> * If you need to access Adapter for additional data, you can call * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the * View. * * @param outRect Rect to receive the output. * @param view The child view to decorate * @param parent RecyclerView this ItemDecoration is decorating * @param state The current state of RecyclerView. */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); // int position = parent.getChildAdapterPosition(view); switch (type) { case HORIZONTAL_LEFT: outRect.left = mSpace; break; case HORIZONTAL_RIGHT: outRect.right = mSpace; break; case VERTICAL_TOP: outRect.top = mSpace; break; case VERTICAL_BOTTOM: outRect.bottom = mSpace; break; } } public RecyclerLinearSpaceItemDecoration(int space, int type) { this.mSpace = space; this.type = type; } }
设置网格布局Item的分割线,目前只实践过可以通过RecyclerView.ItemDecoration来设置,无非就是设置左、右、上、下间隔
public class RecyclerGridSpacingItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; private boolean includeEdge; private Context context; private int styleType; //相同的间隔:横向、纵向、以及头部和底部 private final int STYLE_TYPE_HEAD_FOOT_HORIZONTAL_VERTIAL = 1; //相同的间隔:只有横向、纵向, 没有头部和底部 private final int STYLE_TYPE_HORIZONTAL_VERTIAL = 2; public RecyclerGridSpacingItemDecoration(Context context, int spanCount, int spacing, int styleType ,boolean includeEdge) { this.spanCount = spanCount; this.spacing = spacing; this.includeEdge = includeEdge; this.context = context; this.styleType = styleType; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); // item position int column = position % spanCount; // item column if (includeEdge) { outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing) outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing) if (position < spanCount) { // top edge outRect.top = spacing; } // outRect.bottom = spacing; // item bottom } else { outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing) outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing) switch (styleType) { case STYLE_TYPE_HEAD_FOOT_HORIZONTAL_VERTIAL: //底部有间隔的话,就用top outRect.bottom = spacing; if (position < spanCount) { outRect.top = spacing; } break; case STYLE_TYPE_HORIZONTAL_VERTIAL: if (position >= spanCount) { //底部没有间隔的话,就用top outRect.top = spacing; } break; } } } }