所有的荣誉都归于pskink,他在评论中将此代码链接到了问题。不幸的是,这似乎仍然是唯一的解决方案
// test code
View v = new View(this);
setContentView(v);
Drawable source = getResources().getDrawable(R.drawable.chrome);
Drawable mask = getResources().getDrawable(R.drawable.chrome_mask);;
int[] colors = {
Color.RED, Color.BLACK
};
Drawable shadow = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
Shape s = new S(this, source, mask, shadow, 8);
v.setBackground(new ShapeDrawable(s));
// end of test code
~
class S extends Shape {
Context ctx;
Drawable source;
Drawable mask;
Drawable shadow;
float shadowRadius;
Matrix matrix = new Matrix();
Bitmap bitmap;
public S(Context ctx, Drawable source, Drawable mask, Drawable shadow, float shadowRadius) {
this.ctx = ctx;
this.source = source;
this.mask = mask;
this.shadow = shadow;
this.shadowRadius = shadowRadius;
}
@Override
protected void onResize(float width, float height) {
int intrinsicWidth = source.getIntrinsicWidth();
int intrinsicHeight = source.getIntrinsicHeight();
source.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
mask.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
shadow.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
RectF src = new RectF(0, 0, intrinsicWidth, intrinsicHeight);
RectF dst = new RectF(0, 0, width, height);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
Paint p = new Paint();
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
shadow.draw(c);
c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
mask.draw(c);
c.restore();
bitmap = blurRenderScript(bitmap);
c = new Canvas(bitmap);
int count = c.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
source.draw(c);
c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
mask.draw(c);
c.restoreToCount(count);
}
@Override
public void draw(Canvas canvas, Paint paint) {
canvas.drawColor(0xffdddddd);
canvas.drawBitmap(bitmap, matrix, null);
}
Bitmap blurRenderScript(Bitmap input) {
Bitmap output = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
RenderScript rs = RenderScript.create(ctx);
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation inAlloc = Allocation.createFromBitmap(rs, input, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
Allocation outAlloc = Allocation.createFromBitmap(rs, output);
script.setRadius(shadowRadius);
script.setInput(inAlloc);
script.forEach(outAlloc);
outAlloc.copyTo(output);
rs.destroy();
return output;
}
}
使用上面的解决方案,我对可绘制的圆形进行了此操作:
val source: Drawable = ContextCompat.getDrawable(context,R.drawable.my_drawable)!!
val colors = intArrayOf(
Color.GRAY, Color.TRANSPARENT
)
val shadow: Drawable = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, colors)
val s: Shape = DrawableShadow(context, source, source, shadow, 10f)
imageView.background = ShapeDrawable(s)
imageView.setImageResource(R.drawable.my_drawable)
和我改变的
DrawableShadow
:
class DrawableShadow(
private val context: Context,
private val source: Drawable,
private val mask: Drawable,
private val shadow: Drawable,
private val shadowRadius: Float
) : Shape() {
...
override fun draw(canvas: Canvas, paint: Paint?) {
canvas.drawColor(Color.TRANSPARENT)
...
感谢@pskink的解决方案
如果您已经在使用 compose(或者愿意通过使用 ComposeView 和传统视图方法将其集成到您的项目中),您可以这样做:
Box{
Icon(
imageVector = Icons.Default.ArrowForward,
contentDescription = null,
Modifier
.offset(x = (-1).dp, y = (1).dp)
.blur(4.dp),
tint = Color.Black
)
Icon(
imageVector = Icons.Default.ArrowForward,
contentDescription = null,
tint = Color.White
)
}
可以使用模糊修改器和色调参数进行调整。为了清晰起见,本示例中的图标和值进行了硬编码。