Skip to content

Instantly share code, notes, and snippets.

@wyon
Created July 24, 2017 09:17
Show Gist options
  • Save wyon/d7599bcb0956317dcfaacfa5dd52f0e7 to your computer and use it in GitHub Desktop.
Save wyon/d7599bcb0956317dcfaacfa5dd52f0e7 to your computer and use it in GitHub Desktop.
RecycleView item 边框、阴影
private static class DividerDecoration extends RecyclerView.ItemDecoration {
final int bottomOffset = DisplayUtil.dip2px(15);
final int hOffset = DisplayUtil.dip2px(7);
final ShadowHelper mShadowHelper;
DividerDecoration(Context context) {
mShadowHelper = new ShadowHelper(context);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.bottom = bottomOffset;
final int position = parent.getChildAdapterPosition(view);
if (position == 0) {
return;
}
if (position % 2 == 0) {
outRect.left = hOffset;
} else {
outRect.right = hOffset;
}
}
// @Override
// public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
//public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
// }
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
RecyclerView.LayoutManager layoutManager = null;
int firstVisibleItem = 0, lastVisibleItem = 0;
if (parent.getLayoutManager() instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) parent.getLayoutManager();
firstVisibleItem = gridLayoutManager.findFirstVisibleItemPosition();
lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition();
if (firstVisibleItem != RecyclerView.NO_POSITION && lastVisibleItem != RecyclerView.NO_POSITION) {
layoutManager = gridLayoutManager;
}
} else if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) parent.getLayoutManager();
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (firstVisibleItem != RecyclerView.NO_POSITION && lastVisibleItem != RecyclerView.NO_POSITION) {
layoutManager = linearLayoutManager;
}
}
if (layoutManager == null) {
return;
}
View item;
for (; firstVisibleItem <= lastVisibleItem; firstVisibleItem++) {
item = layoutManager.findViewByPosition(firstVisibleItem);
mShadowHelper.drawShadow(c, item);
}
}
}
private static class ShadowHelper {
final int shadowStartColor = 0x37000000;
final int shadowEndColor = 0x03000000;
final int cornerRadius = (int) (DisplayUtil.dip2px(6) + .5f);
final int shadowSize = DisplayUtil.dip2px(5);
final Rect tmpRect = new Rect();
Path cornerShadowPath;
Paint cornerShadowPaint;
Paint edgeShadowPaint;
Paint testPaint;
ShadowHelper(Context context) {
cornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
cornerShadowPaint.setStyle(Paint.Style.FILL);
edgeShadowPaint = new Paint(cornerShadowPaint);
edgeShadowPaint.setAntiAlias(false);
RectF innerBounds = new RectF(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius);
RectF outerBounds = new RectF(innerBounds);
outerBounds.inset(-shadowSize, -shadowSize);
cornerShadowPath = new Path();
cornerShadowPath.setFillType(Path.FillType.EVEN_ODD);
cornerShadowPath.moveTo(-cornerRadius, 0);
cornerShadowPath.rLineTo(-shadowSize, 0);
// outer arc
cornerShadowPath.arcTo(outerBounds, 180f, 90f, false);
// inner arc
cornerShadowPath.arcTo(innerBounds, 270f, -90f, false);
cornerShadowPath.close();
// final float startRatio = cornerRadius / (cornerRadius + shadowSize);
cornerShadowPaint.setShader(new RadialGradient(0, 0, cornerRadius + shadowSize,
new int[]{shadowStartColor, shadowStartColor, shadowEndColor},
new float[]{0f, .6f, 1f}, Shader.TileMode.CLAMP));
edgeShadowPaint.setShader(new LinearGradient(0, -cornerRadius + shadowSize,
0, -cornerRadius - shadowSize,
new int[]{shadowStartColor, shadowStartColor, shadowEndColor},
new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP));
testPaint = new Paint();
testPaint.setStyle(Paint.Style.FILL);
testPaint.setColor(Color.RED);
// testPaint.setStrokeWidth(2);
}
// private void drawShadow(Canvas c, View item) {
// final float edgeShadowTop = -cornerRadius - shadowSize;
// final float inset = cornerRadius + shadowSize / 2;
// tmpRect.set(item.getLeft(), item.getTop(), item.getRight(), item.getBottom());
// // LT
// int saved = c.save();
// c.translate(tmpRect.left + inset, tmpRect.top + inset);
//// c.drawPath(cornerShadowPath, cornerShadowPaint);
// testPaint.setColor(Color.RED);
// c.drawPath(cornerShadowPath, testPaint);
// // draw horizontal edge
//// c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius, edgeShadowPaint);
// testPaint.setColor(Color.GREEN);
// c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius, testPaint);
// c.restoreToCount(saved);
// // RB
//// saved = c.save();
//// c.translate(tmpRect.right - inset, tmpRect.bottom - inset);
//// c.rotate(180f);
////// c.drawPath(cornerShadowPath, cornerShadowPaint);
//// testPaint.setColor(Color.RED);
//// c.drawPath(cornerShadowPath, testPaint);
//// // draw horizontal edge
////// c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius + shadowSize, edgeShadowPaint);
//// testPaint.setColor(Color.GREEN);
//// c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius + shadowSize, testPaint);
//// c.restoreToCount(saved);
// // LB
// saved = c.save();
// c.translate(tmpRect.left + inset, tmpRect.bottom - inset);
// c.rotate(270f);
//// c.drawPath(cornerShadowPath, cornerShadowPaint);
// testPaint.setColor(Color.RED);
// c.drawPath(cornerShadowPath, testPaint);
// // draw vertical edge
//// c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, edgeShadowPaint);
// testPaint.setColor(Color.GREEN);
// c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, testPaint);
// c.restoreToCount(saved);
// // RT
//// saved = c.save();
//// c.translate(tmpRect.right - inset, tmpRect.top + inset);
//// c.rotate(90f);
////// c.drawPath(cornerShadowPath, cornerShadowPaint);
//// testPaint.setColor(Color.RED);
//// c.drawPath(cornerShadowPath, testPaint);
//// // draw vertical edge
////// c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, edgeShadowPaint);
//// testPaint.setColor(Color.GREEN);
//// c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, testPaint);
//// c.restoreToCount(saved);
// }
private void drawShadow(Canvas c, View item) {
final float edgeShadowTop = -cornerRadius - shadowSize;
final float inset = cornerRadius + shadowSize / 2;
tmpRect.set(item.getLeft(), item.getTop(), item.getRight(), item.getBottom());
// LT
int saved = c.save();
c.translate(tmpRect.left + inset, tmpRect.top + inset);
c.drawPath(cornerShadowPath, cornerShadowPaint);
// draw horizontal edge
c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius, edgeShadowPaint);
c.restoreToCount(saved);
// RB
saved = c.save();
c.translate(tmpRect.right - inset, tmpRect.bottom - inset);
c.rotate(180f);
c.drawPath(cornerShadowPath, cornerShadowPaint);
// draw horizontal edge
c.drawRect(0, edgeShadowTop, tmpRect.width() - 2 * inset, -cornerRadius + shadowSize, edgeShadowPaint);
c.restoreToCount(saved);
// LB
saved = c.save();
c.translate(tmpRect.left + inset, tmpRect.bottom - inset);
c.rotate(270f);
c.drawPath(cornerShadowPath, cornerShadowPaint);
// draw vertical edge
c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, edgeShadowPaint);
c.restoreToCount(saved);
// RT
saved = c.save();
c.translate(tmpRect.right - inset, tmpRect.top + inset);
c.rotate(90f);
c.drawPath(cornerShadowPath, cornerShadowPaint);
// draw vertical edge
c.drawRect(0, edgeShadowTop, tmpRect.height() - 2 * inset, -cornerRadius, edgeShadowPaint);
c.restoreToCount(saved);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment