预览
实现方式
视频合辑这个Item上面的遮罩层一直没找到很好的方法,所以有自己撸了一个库来支持,特此也写一章
PASS找实现快捷方法的心酸历程。。。
仔细细扫网易云App,发现它的这层模糊效果是直接模糊了图片叠加在上面的,想到的就是通过google RenderScript来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
private const val BITMAP_SCALE = 0.4f
private const val BLUR_RADIUS = 25f
fun Context.blur(image: Bitmap): Bitmap { val width = (image.width * BITMAP_SCALE).roundToInt() val height = (image.height * BITMAP_SCALE).roundToInt()
val inputBitmap = Bitmap.createScaledBitmap(image, width, height, false) val outputBitmap = Bitmap.createBitmap(inputBitmap)
val rs = RenderScript.create(this) val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
val tmpIn = Allocation.createFromBitmap(rs, inputBitmap) val tmpOut = Allocation.createFromBitmap(rs, outputBitmap)
blurScript.setRadius(BLUR_RADIUS) blurScript.setInput(tmpIn) blurScript.forEach(tmpOut)
tmpOut.copyTo(outputBitmap)
return outputBitmap }
|
中间镂空状态是通过Canvas.clipPath()
剪切来达到效果
1 2 3 4 5 6 7 8
| blurBitmap?.let { canvas.drawBitmap(it, null, bounds, null) } ?: canvas.drawColor(defaultCoverColor)
canvas.clipPath(clipPath)
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC)
|
四边上的装饰边线也是通过Path()
描绘四边绘制实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| val rectF = RectF()
rectF.set( paddingStartEnd, paddingTopBottom, paddingStartEnd + roundCorner * 2, paddingTopBottom + roundCorner * 2 ) strokePath.reset() strokePath.arcTo(rectF, 180f, 90f, true)
rectF.set( width - paddingStartEnd - roundCorner * 2, paddingTopBottom, width - paddingStartEnd, paddingTopBottom + roundCorner * 2 ) strokePath.arcTo(rectF, 270f, 90f, true)
rectF.set( width - paddingStartEnd - roundCorner * 2, height - paddingTopBottom - roundCorner * 2, width - paddingStartEnd, height - paddingTopBottom ) strokePath.arcTo(rectF, 0f, 90f, true)
rectF.set( paddingStartEnd, height - paddingTopBottom - roundCorner * 2, paddingStartEnd + roundCorner * 2, height - paddingTopBottom ) strokePath.arcTo(rectF, 90f, 90f, true)
|
通过实现这些的前奏,再稍加修饰调整属性,最终得到想要的效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <com.xuie0000.hollowout.drawable.HollowOutShapeableImageView android:id="@+id/ivImage" android:layout_width="120dp" android:layout_height="120dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:background="@color/white80" android:scaleType="centerCrop" app:hollow_out_padding_horizontal="4dp" app:hollow_out_padding_vertical="32dp" app:hollow_out_round_corner="8dp" app:hollow_out_round_corner_color="@color/white" app:hollow_out_round_corner_stroke="2dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:shapeAppearanceOverlay="@style/roundedCornerStyle" tools:src="@mipmap/ic_netease" />
|
参考
https://github.com/xuie0000/hollowout-drawable
https://zhuanlan.zhihu.com/p/329825945
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0816/6543.html
https://developer.android.com/guide/topics/renderscript/compute.html