1. ItemDecoration類的定義
ItemDecoration-->RecycleView的item系統(tǒng)間距以及系統(tǒng)item繪制封裝類
/**
* ItemDecoration允許程序?qū)m配器的數(shù)據(jù)源中的特殊的條目
* view 添加一些特別的圖形和布局的偏移,這被用于在條目之
* 間畫(huà)間隔線,高亮顯示隆圆,視覺(jué)分組界限和更多响鹃。
* 所有的ItemDecorations
* <p>所有的ItemDecorations都是按照它們添加的順序繪制的,
* 在所有的條目view繪制之前
* (in {@link ItemDecoration#onDraw(Canvas, RecyclerView, RecyclerView.State) onDraw()}
* 在所有的條目view繪制之后 (in {@link ItemDecoration#onDrawOver(Canvas, RecyclerView,
* RecyclerView.State)}.</p>
*/
public abstract static class ItemDecoration {
...
...
}
2. ItemDecoration的方法分析
此類下的六個(gè)方法有三個(gè)為過(guò)時(shí)方法蜕提,只需要復(fù)寫另外三個(gè)未過(guò)時(shí)的方法即可宴抚,谷歌對(duì)這三個(gè)方法的定義如下:
- 在提供給RecyclerView的Canvas中繪制任何適當(dāng)?shù)难b飾梢什。 此方法繪制的任何內(nèi)容將在繪制項(xiàng)目視圖之前繪制布轿, 因此將被視圖覆蓋.
public void onDraw(Canvas c, RecyclerView parent, State state{
onDraw(c, parent);
}
- 在提供給RecyclerView的Canvas中繪制任何適當(dāng)?shù)难b飾哮笆。 此方法繪制的任何內(nèi)容將在繪制項(xiàng)目視圖之后繪制, 因此將覆蓋視圖
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
}
- 檢索給定條目的所有偏移量汰扭, outRect 的每個(gè)字段指定條目視圖應(yīng)該被插入的像素大小稠肘,類似于填充或邊距。默認(rèn)實(shí)現(xiàn)將outRect的邊界設(shè)置為0并返回萝毛。
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams)view.getLayoutParams()).getViewLayoutPosition(), parent);
}
注:onDraw 和 onDrawOver的區(qū)別在于项阴,若未規(guī)定條目視圖的左上右下的偏移量,在條目視圖的基礎(chǔ)上笆包,使用canvas 所做的任何裝飾环揽,前者會(huì)被條目視圖所覆蓋,而后者方法則會(huì)在條目視圖的基礎(chǔ)上作畫(huà)庵佣。
3. 封裝 getItemOffsets
- 通過(guò)構(gòu)造函數(shù)傳入左上右下的間距
private int mSpaceHorizontal;
private int mSpaceVertical;
private Paint mPaint;
DividerDecoration(Activity activity, int spaceHorizontal, int spaceVertical) {
mSpaceHorizontal = spaceHorizontal;
mSpaceVertical = spaceVertical;
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setColor(ContextCompat.getColor(activity, android.R.color.transparent));
}
DividerDecoration(Activity activity, int color, int spaceHorizontal, int spaceVertical) {
mSpaceHorizontal = spaceHorizontal;
mSpaceVertical = spaceVertical;
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setColor(ContextCompat.getColor(activity, color));
}
- 篩選RecycleView的布局管理器 歉胶,對(duì)應(yīng)做單獨(dú)處理
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
layoutGridItem(outRect, view, parent, (GridLayoutManager) layoutManager);
} else if (layoutManager instanceof LinearLayoutManager) {
layoutLinearItem(outRect, view, parent, (LinearLayoutManager) layoutManager);
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
layoutStaggeredItem(outRect, view, parent, (StaggeredGridLayoutManager) layoutManager);
}
}
- LinearLayoutManager 的布局偏移封裝
private void layoutLinearItemSpace(Rect outRect, View view, RecyclerView parent, LinearLayoutManager linearManager) {
int viewPosition = parent.getChildAdapterPosition(view);
if (linearManager.getOrientation() == LinearLayoutManager.VERTICAL) {
outRect.left = mSpaceHorizontal;
outRect.right = mSpaceHorizontal;
if (viewPosition == 0) {
outRect.top = mSpaceVertical;
outRect.bottom = mSpaceVertical / 2;
} else if (viewPosition == linearManager.getItemCount() - 1) {
outRect.top = mSpaceVertical / 2;
outRect.bottom = mSpaceVertical;
} else {
outRect.top = mSpaceVertical / 2;
outRect.bottom = mSpaceVertical / 2;
}
} else {
outRect.top = mSpaceVertical;
outRect.bottom = mSpaceVertical;
if (viewPosition == 0) {
outRect.left = mSpaceHorizontal;
outRect.right = mSpaceHorizontal / 2;
} else if (viewPosition == linearManager.getItemCount() - 1) {
outRect.left = mSpaceHorizontal / 2;
outRect.right = mSpaceHorizontal;
} else {
outRect.left = mSpaceHorizontal / 2;
outRect.right = mSpaceHorizontal / 2;
}
}
}
- GridLayoutManager 的布局偏移封裝
private void layoutGridItemSpace(Rect outRect, View view, RecyclerView parent, GridLayoutManager gridManager) {
int viewPosition = parent.getChildAdapterPosition(view);
int spanCount = gridManager.getSpanCount();
int index = viewPosition % spanCount;
if (viewPosition < spanCount) {//第一行
outRect.top = mSpaceVertical;
outRect.bottom = mSpaceVertical / 2;
} else if (viewPosition / spanCount == (gridManager.getItemCount() - 1) / spanCount) {//多宮格如何判斷最后一行?
outRect.top = mSpaceVertical / 2;
outRect.bottom = mSpaceVertical;
} else {
outRect.top = mSpaceVertical / 2;
outRect.bottom = mSpaceVertical / 2;
}
if (index == 0) {//第一列
outRect.left = mSpaceHorizontal;
outRect.right = mSpaceHorizontal / 2;
} else if (index == spanCount - 1) {//最后一列
outRect.left = mSpaceHorizontal / 2;
outRect.right = mSpaceHorizontal;
} else {
outRect.left = mSpaceHorizontal / 2;
outRect.right = mSpaceHorizontal / 2;
}
}
- StaggeredGridLayoutManager的布局偏移封裝
private void layoutStaggeredItemSpace(Rect outRect, View view, RecyclerView parent, StaggeredGridLayoutManager staggeredManager) {
}
- LinearLayoutManager 的布局偏移顏色封裝
private void drawLinearItemSpace(Canvas c, RecyclerView parent, LinearLayoutManager linearManager) {
if (linearManager.getOrientation() == LinearLayoutManager.VERTICAL) {
for (int viewPosition = 0; viewPosition < linearManager.getItemCount(); viewPosition++) {
View childView = parent.getChildAt(viewPosition);
if (childView == null) {
continue;
}
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams();
int left;
int top;
int right;
int bottom;
left = childView.getLeft() - params.leftMargin;
right = childView.getRight() + params.rightMargin;
top = childView.getBottom() + params.bottomMargin;
bottom = top + mSpaceVertical;
c.drawRect(left, top, right, bottom, mPaint);
if (viewPosition == 0) {
top = childView.getTop() - params.topMargin - mSpaceVertical;
bottom = top + mSpaceVertical;
c.drawRect(left, top, right, bottom, mPaint);
}
}
} else {
for (int viewPosition = 0; viewPosition < linearManager.getItemCount(); viewPosition++) {
View childView = parent.getChildAt(viewPosition);
if (childView == null) {
continue;
}
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams();
int left;
int top;
int right;
int bottom;
left = childView.getRight() + params.rightMargin;
top = childView.getTop() - params.topMargin;
right = left + mSpaceHorizontal;
bottom = childView.getBottom() + params.bottomMargin;
c.drawRect(left, top, right, bottom, mPaint);
if(viewPosition == 0) {
left = childView.getLeft() - params.leftMargin - mSpaceHorizontal;
top = childView.getTop() - params.topMargin;
right = left + mSpaceHorizontal;
bottom = childView.getBottom() + params.bottomMargin;
c.drawRect(left, top, right, bottom, mPaint);
}
}
}
}
- GridLayoutManager 的布局顏色填充封裝
private void drawGridItemSpace(Canvas c, RecyclerView parent, GridLayoutManager gridManager) {
for (int viewPosition = 0; viewPosition < gridManager.getItemCount(); viewPosition++) {
View childView = parent.getChildAt(viewPosition);
if (childView == null) {
continue;
}
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams();
int spanCount = gridManager.getSpanCount();
int index = viewPosition % spanCount;
int left;
int top;
int right;
int bottom;
left = childView.getLeft() - params.leftMargin;
right = childView.getRight() + params.rightMargin + mSpaceHorizontal;
if (viewPosition < spanCount) {//第一行
top = childView.getTop() - params.topMargin - mSpaceVertical;
bottom = top + mSpaceVertical;
c.drawRect(left, top, right, bottom, mPaint);
top = childView.getBottom() + params.bottomMargin;
bottom = top + mSpaceVertical;
c.drawRect(left, top, right, bottom, mPaint);
} else {
top = childView.getBottom() + params.bottomMargin;
bottom = top + mSpaceVertical;
c.drawRect(left, top, right, bottom, mPaint);
}
if (index == 0) {//第一列
top = childView.getTop() - params.topMargin;
bottom = childView.getBottom() + params.bottomMargin + mSpaceVertical;
left = childView.getLeft() - params.leftMargin - mSpaceHorizontal;
right = left + mSpaceHorizontal;
c.drawRect(left, top, right, bottom, mPaint);
top = childView.getTop() - params.topMargin;
bottom = childView.getBottom() + params.bottomMargin;
left = childView.getRight() + params.rightMargin;
right = left + mSpaceHorizontal;
c.drawRect(left, top, right, bottom, mPaint);
if (viewPosition == 0) {
top = childView.getTop() - params.topMargin - mSpaceVertical;
bottom = top + mSpaceVertical;
left = childView.getLeft() - params.leftMargin - mSpaceHorizontal;
right = left + mSpaceHorizontal;
c.drawRect(left, top, right, bottom, mPaint);
}
} else {
top = childView.getTop() - params.topMargin;
bottom = childView.getBottom() + params.bottomMargin;
left = childView.getRight() + params.rightMargin;
right = left + mSpaceHorizontal;
c.drawRect(left, top, right, bottom, mPaint);
}
}
}
- StaggeredGridLayoutManager的布局偏移顏色填充封裝
StaggeredGridLayoutManager 相關(guān)的目前正在研究巴粪,后面會(huì)補(bǔ)充完善