You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程为Drawable对象(应用图标)设置圆角或圆形样式?

当然可行!我之前在项目里刚好处理过类似的需求,不管是你已经获取到的应用启动器Drawable,还是其他任意Drawable,都能轻松把它改成圆形或者圆角样式,下面给你两种实用的实现方案:

方案一:自定义RoundDrawable类(灵活可控)

这种方法是通过自定义Drawable子类,利用BitmapShader来实现圆形/圆角效果,好处是可以直接复用,还能动态调整圆角大小。

实现步骤:

  1. 创建RoundDrawable类,继承自Drawable,核心是在onDraw()方法里用Shader绘制带圆角的图形:
public class RoundDrawable extends Drawable {
    private Paint mPaint;
    private Bitmap mBitmap;
    private RectF mRectF;
    private float mRadius; // 圆角半径,设为Bitmap宽高一半就是圆形

    public RoundDrawable(Bitmap bitmap, float radius) {
        mBitmap = bitmap;
        mRadius = radius;
        BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(shader);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mRectF = new RectF(bounds);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        // 绘制圆角矩形,mRadius设为宽高一半就是圆形
        canvas.drawRoundRect(mRectF, mRadius, mRadius, mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        invalidateSelf();
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    // 提供静态方法,直接将Drawable转为RoundDrawable
    public static RoundDrawable fromDrawable(Drawable drawable, float radius) {
        if (drawable instanceof BitmapDrawable) {
            return new RoundDrawable(((BitmapDrawable) drawable).getBitmap(), radius);
        }
        // 非BitmapDrawable的情况,先转成Bitmap
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return new RoundDrawable(bitmap, radius);
    }
}
  1. 使用的时候,直接把你拿到的启动器Drawable传进去就行:
// 假设你已经获取到了应用的启动器Drawable:appIconDrawable
// 转成圆形(圆角半径设为宽高的一半)
float radius = Math.min(appIconDrawable.getIntrinsicWidth(), appIconDrawable.getIntrinsicHeight()) / 2f;
RoundDrawable roundIcon = RoundDrawable.fromDrawable(appIconDrawable, radius);

// 如果要转成圆角矩形,比如16dp的圆角
float dp16 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics());
RoundDrawable roundedCornerIcon = RoundDrawable.fromDrawable(appIconDrawable, dp16);

// 然后就可以把roundIcon设置给ImageView或者其他View了
imageView.setImageDrawable(roundIcon);
方案二:直接用Canvas裁剪(快速实现)

如果只是临时处理某个Drawable,不想写自定义类,可以直接把Drawable转为Bitmap,然后用Canvas的裁剪逻辑处理,再转成Drawable:

public static Drawable getRoundedDrawable(Drawable drawable, float radius) {
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    // 创建裁剪后的Bitmap
    Bitmap roundedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas roundedCanvas = new Canvas(roundedBitmap);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    RectF rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
    // 先绘制圆角路径,再用SRC_IN模式叠加原Bitmap
    roundedCanvas.drawRoundRect(rectF, radius, radius, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    roundedCanvas.drawBitmap(bitmap, 0, 0, paint);

    return new BitmapDrawable(roundedBitmap);
}

// 使用示例:
Drawable roundedIcon = getRoundedDrawable(appIconDrawable, dp16);
imageView.setImageDrawable(roundedIcon);

注意事项:

  • 如果你的Drawable是矢量图(VectorDrawable),转Bitmap的时候要注意设置正确的宽高,避免模糊;
  • 两种方法都要记得处理Bitmap的回收,避免内存泄漏,尤其是在列表中使用的时候;
  • 方案一的自定义Drawable更适合复用,比如在多个地方需要圆形/圆角图标时,推荐用这个方案。

内容的提问来源于stack exchange,提问作者java

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:48:16