Android中自定义RecyclerView.ItemDecoration
程序员文章站
2022-07-01 16:33:15
在Android应用开发中,往往显示列表都是需要用到RecyclerView的,而RecyclerView默认是没有item的分隔线的,需要调用addItemDecoration添加分隔线,你可以用它自带的DividerItemDecoration,也可以自己去继承RecyclerView.ItemDecoration来实现分隔线功能,下面我就具体来讲解下怎么自己绘制分隔线。需要重写的方法有:onDraw和getItemOffsets,还有可能重写onDrawOver。onDraw():绘制分隔...
在Android应用开发中,往往显示列表都是需要用到RecyclerView的,而RecyclerView默认是没有item的分隔线的,需要调用addItemDecoration添加分隔线,你可以用它自带的DividerItemDecoration,也可以自己去继承RecyclerView.ItemDecoration来实现分隔线功能,下面我就具体来讲解下怎么自己绘制分隔线。
需要重写的方法有:
onDraw和getItemOffsets,还有可能重写onDrawOver。
onDraw():绘制分隔线的具体绘制代码
onDrawOver():在item绘制完成之后,添加绘制一点东西,它和onDraw的区别在于onDraw在绘制itemView之前,而它在绘制itemView之后
getItemOffsets():设置绘制item的偏移位置,通过改变outRect的left、top、right、bottom的值来指定偏移位置,默认这4个值都为0,表示不偏移,即根据原item的宽度和高度绘制,如果不预留出位置的话,下一个item就会覆盖掉当前的分隔线的绘制。而要预留出位置,如果是垂直排列的条目,你可以这样设置outRect。
outRect.bottom = mDividerHeight;
下面看一下RecyclerView的draw()和onDraw()方法,分析过View绘制流程的就知道,View会在draw()方法里面调用onDraw(),在RecyclerView的onDraw()方法中会绘制itemDecoration的onDraw()方法和itemView的内容,绘制完成后才会绘制onDrawOver()中需要绘制的内容。
@Override
public void draw(Canvas c) {
super.draw(c);
final int count = mItemDecorations.size();
for (int i = 0; i < count; i++) {
mItemDecorations.get(i).onDrawOver(c, this, mState);
}
// TODO If padding is not 0 and clipChildrenToPadding is false, to draw glows properly, we
// need find children closest to edges. Not sure if it is worth the effort.
boolean needsInvalidate = false;
if (mLeftGlow != null && !mLeftGlow.isFinished()) {
final int restore = c.save();
final int padding = mClipToPadding ? getPaddingBottom() : 0;
c.rotate(270);
c.translate(-getHeight() + padding, 0);
needsInvalidate = mLeftGlow != null && mLeftGlow.draw(c);
c.restoreToCount(restore);
}
if (mTopGlow != null && !mTopGlow.isFinished()) {
final int restore = c.save();
if (mClipToPadding) {
c.translate(getPaddingLeft(), getPaddingTop());
}
needsInvalidate |= mTopGlow != null && mTopGlow.draw(c);
c.restoreToCount(restore);
}
if (mRightGlow != null && !mRightGlow.isFinished()) {
final int restore = c.save();
final int width = getWidth();
final int padding = mClipToPadding ? getPaddingTop() : 0;
c.rotate(90);
c.translate(-padding, -width);
needsInvalidate |= mRightGlow != null && mRightGlow.draw(c);
c.restoreToCount(restore);
}
if (mBottomGlow != null && !mBottomGlow.isFinished()) {
final int restore = c.save();
c.rotate(180);
if (mClipToPadding) {
c.translate(-getWidth() + getPaddingRight(), -getHeight() + getPaddingBottom());
} else {
c.translate(-getWidth(), -getHeight());
}
needsInvalidate |= mBottomGlow != null && mBottomGlow.draw(c);
c.restoreToCount(restore);
}
// If some views are animating, ItemDecorators are likely to move/change with them.
// Invalidate RecyclerView to re-draw decorators. This is still efficient because children's
// display lists are not invalidated.
if (!needsInvalidate && mItemAnimator != null && mItemDecorations.size() > 0
&& mItemAnimator.isRunning()) {
needsInvalidate = true;
}
if (needsInvalidate) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
@Override
public void onDraw(Canvas c) {
super.onDraw(c);
final int count = mItemDecorations.size();
for (int i = 0; i < count; i++) {
mItemDecorations.get(i).onDraw(c, this, mState);
}
}
本文地址:https://blog.csdn.net/a_lwh____/article/details/107378053
推荐阅读
-
Android自定义Drawable实现圆形和圆角
-
Android自定义水平渐变进度条
-
Android 中利用 ksoap2 调用 WebService的示例代码
-
Android开发中播放声音的两种方法分析
-
Android 中Failed to read key from keystore解决办法
-
Android开发中数据库升级且表添加新列的方法
-
Android开发中Eclipse报错及对应处理方法总结
-
Android Studio中快捷键实现try catch等功能包含代码块的实现方法
-
Android不使用自定义布局情况下实现自定义通知栏图标的方法
-
详解Android中IntentService的使用方法