Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 绘制CircularImage时XY错误大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在 Android中编写自定义的Circular ImageView.我需要在它上面设置一个Drawable覆盖,所以我选择编写一个自定义的CircularImageView,它将图片本身保存为drawable.

其实我有两个问题:

>图像是左上角绘制的,我需要将它绘制在视图的中心
>我需要我的王冠更大(可绘制),但我不知道如何调整它.

一些imgs澄清:

我想要实现的目标:

android – 绘制CircularImage时XY错误


我现在拥有的东西:(请不要虑黑框边框,只是为了澄清@L_673_9@的图像“重力”)

android – 绘制CircularImage时XY错误

我的观点代码

public class CrownCircularImageView extends ImageView {

    private Drawable crown;
    privatE int canvasSize;
    privatE int crownWidth;
    privatE int crownHeight;

    // Object used to draw
    private Bitmap image;
    private Drawable drawable;
    private Paint paint;
    private Paint crownPaint;

    public CrownCircularImageView(Context context) {
        this(context,null,0);
    }

    public CrownCircularImageView(Context context,AttributeSet attrs) {
        this(context,attrs,AttributeSet attrs,int defStyleAttr) {
        super(context,defStyleAttr);
        init(context,defStyleAttr);
    }

    private void init(Context context,int defStyleAttr) {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        crownPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.crown = ContextCompat.getDrawable(context,R.drawable.ic_crown);
    }

    private void loadBitmap() {
        if (this.drawable == getDrawable())
            return;

        this.drawable = getDrawable();
        this.image = drawableToBitmap(this.drawablE);
        updateShader();
    }

    @Override
    protected void onSizeChanged(int w,int h,int oldw,int oldh) {
        super.onSizeChanged(w,h,oldw,oldh);
        canvasSize = w - crownWidth;
        if (h < canvasSizE)
            canvasSize = h - crownHeight;
        if (image != null)
            updateShader();
    }

    private void updateShader() {
        if (image == null)
            return;

        // Crop Center Image
        image = cropBitmap(imagE);

        // Create Shader
        BitmapShader shader = new BitmapShader(image,Shader.TileMode.CLAMP,Shader.TileMode.CLAMp);

        // Center Image in Shader
        Matrix matrix = new Matrix();
        matrix.setScale((float) canvasSize / (float) image.getWidth(),(float) canvasSize / (float) image.getHeight());
        shader.setLocalMatrix(matriX);

        // Set Shader in Paint
        paint.setShader(shader);
    }

    private Bitmap cropBitmap(Bitmap bitmap) {
        Bitmap bmp;
        if (bitmap.getWidth() >= bitmap.getHeight()) {
            bmp = Bitmap.createBitmap(
                    bitmap,bitmap.getWidth() / 2 - bitmap.getHeight() / 2,bitmap.getHeight(),bitmap.getHeight());
        } else {
            bmp = Bitmap.createBitmap(
                    bitmap,bitmap.getHeight() / 2 - bitmap.getWidth() / 2,bitmap.getWidth(),bitmap.getWidth());
        }
        return bmp;
    }

    private Bitmap drawableToBitmap(Drawable drawablE) {
        if (drawable == null) {
            return null;
        } else if (drawable instanceof BitmapDrawablE) {
            return ((BitmapDrawablE) drawablE).getBitmap();
        }

        int intrinsicWidth = drawable.geTintrinsicWidth();
        int intrinsicHeight = drawable.geTintrinsicHeight();

        if (!(intrinsicWidth > 0 && intrinsicHeight > 0))
            return null;

        try {
            // Create Bitmap object out of the drawable
            Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth,intrinsicHeight,Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0,canvas.getWidth(),canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (OutOfMemoryError E) {
            // Simply return null of Failed bitmap creations
            Log.e(getClass().toString(),"Encountered OutOfMemoryError while generating bitmap!");
            return null;
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        // Load the bitmap
        loadBitmap();

        // check if image isn't null
        if (image == null)
            return;

        if (!isInEditMode()) {
            canvasSize = canvas.getWidth();
            if (canvas.getHeight() < canvasSizE) {
                canvasSize = canvas.getHeight();
            }
        }

        int circleCenter = (canvasSize - crownHeight) / 2;
        int cx = (canvasSize - crownWidth) / 2;
        int cy = (canvasSize - crownHeight) / 2;

        Bitmap crownBmp = drawableToBitmap(crown);

        int crownX = cx;
        int crownY = cy;

        canvas.drawCircle(cx,cy,circleCenter,paint);
        canvas.drawBitmap(crownBmp,crownX,crownY,crownPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpeC) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);

        crownWidth = crown.geTintrinsicWidth();
        crownHeight = crown.geTintrinsicHeight();

        setMeasuredDimension(width,height);
    }

    @Override
    public ScaleType getScaleType() {
        return ScaleType.CENTER_CROP;
    }

    privatE int measureWidth(int measureSpeC) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // The parent has determined an exact size for the child.
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // The parent has not imposed any consTraint on the child.
            result = canvasSize;
        }

        return result + crown.geTintrinsicWidth();
    }

    privatE int measureHeight(int measureSpecHeight) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = canvasSize;
        }

        return (result + 2 + crown.geTintrinsicHeight());
    }

}

解决方法

可以创建一个新的位图,使用圆形蒙版在透明背景上绘制旧位图,然后在其上绘制表冠.此示例还允许在图像周围添加填充.

您需要调整CIRCLE_PADDING和RESIZE_CROWN_FACTOR的值以满足您的需求.

public class CrownImageView extends ImageView {
    private static final int CIRCLE_PADDING = 25;
    private static final float RESIZE_CROWN_FACTOR = 1.5f;

    private Bitmap rounded;
    private Bitmap resizedCrown;

    public CrownImageView(final Context context) {
        super(context);
    }

    public CrownImageView(final Context context,final AttributeSet attrs) {
        super(context,attrs);
    }

    public CrownImageView(final Context context,final AttributeSet attrs,final int defStyleAttr) {
        super(context,defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();

        if (drawable == null || getWidth() == 0 || getHeight() == 0) {
            return;
        }

        if (resizedCrown == null) {
            loadCrown();
        }

        loadImage(drawablE);

        canvas.drawBitmap(rounded,null);
        canvas.drawBitmap(resizedCrown,canvas.getWidth() - resizedCrown.getWidth(),null);
    }

    private void loadImage(Drawable drawablE) {
        Bitmap bmp = bitmapFromDrawable(drawablE);

        final Rect rect = new Rect(0,bmp.getWidth(),bmp.getHeight());

        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);

        rounded = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),Bitmap.Config.ARGB_8888);

        Canvas newCanvas = new Canvas(rounded);
        newCanvas.drawARGB(0,0);

        float centerX = getWidth() / 2;
        float centerY = getHeight() / 2;
        float radius = Math.min(getWidth(),getHeight()) / 2 - CIRCLE_PADDING;
        newCanvas.drawCircle(centerX,centerY,radius,paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        newCanvas.drawBitmap(bmp,rect,paint);
    }

    private void loadCrown() {
        Bitmap crown = BitmapFactory.decoderesource(getresources(),R.drawable.crown);
        resizedCrown = Bitmap.createScaledBitmap(crown,(int) (crown.getWidth() * RESIZE_CROWN_FACTOR),(int) (crown.getHeight() * RESIZE_CROWN_FACTOR),truE);
    }

    private Bitmap bitmapFromDrawable(Drawable drawablE) {
        Bitmap bmp;

        if (drawable instanceof BitmapDrawablE) {
            bmp = ((BitmapDrawablE) drawablE).getBitmap();
        } else {
            bmp = Bitmap.createBitmap(drawable.geTintrinsicWidth(),drawable.geTintrinsicHeight(),Bitmap.Config.ARGB_8888);
            Canvas bmpCanvas = new Canvas(bmp);
            drawable.setBounds(0,bmpCanvas.getWidth(),bmpCanvas.getHeight());
            drawable.draw(bmpCanvas);
        }

        return bmp;
    }
}

更新:您可以像这样使用Glide

final CrownImageView imageView = (CrownImageView) findViewById(R.id.fragment_kids_row_img_kids);
Glide.with(this).load(yourimageurl).into(imageView);

大佬总结

以上是大佬教程为你收集整理的android – 绘制CircularImage时XY错误全部内容,希望文章能够帮你解决android – 绘制CircularImage时XY错误所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。