且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在不创建新位图的情况下拥有圆形、居中裁剪的 imageView?

更新时间:2023-09-20 09:12:16

试试这个极简的自定义 Drawable 并修改它以满足您的需求:

try this minimalist custom Drawable and modify it to meet your needs:

class D extends Drawable {
    Bitmap bitmap;
    Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    int side;
    float radius;

    public D(Bitmap wrappedBitmap) {
        bitmap = wrappedBitmap;
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(16);
        borderPaint.setColor(0xcc220088);
        side = Math.min(bitmap.getWidth(), bitmap.getHeight());
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        Matrix matrix = new Matrix();
        RectF src = new RectF(0, 0, side, side);
        src.offset((bitmap.getWidth() - side) / 2f, (bitmap.getHeight() - side) / 2f);
        RectF dst = new RectF(bounds);
        dst.inset(borderPaint.getStrokeWidth(), borderPaint.getStrokeWidth());
        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        shader.setLocalMatrix(matrix);
        maskPaint.setShader(shader);
        matrix.mapRect(src);
        radius = src.width() / 2f;
    }

    @Override
    public void draw(Canvas canvas) {
        Rect b = getBounds();
        canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), radius, maskPaint);
        canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), radius + borderPaint.getStrokeWidth() / 2, borderPaint);
    }

    @Override public void setAlpha(int alpha) {}
    @Override public void setColorFilter(ColorFilter cf) {}
    @Override public int getOpacity() {return PixelFormat.TRANSLUCENT;}
}