Created
July 24, 2017 09:17
-
-
Save wyon/d7599bcb0956317dcfaacfa5dd52f0e7 to your computer and use it in GitHub Desktop.
RecycleView item 边框、阴影
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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