ImageView setImageResource 无效,记一个bug

package com.example.superdy.test;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.ImageView;


/**
 * A widget to display circular photo.
 */
public class CircularPhotoView extends ImageView {

    private int mBorderWidth;
    private int mCanvasSize;
    private Paint mPaint;
    private Paint mPaintBorder;
    private Paint mPaintBg;
    private Paint mNotifyDotPaint;
    private Paint mNotifyDotBorderPaint;
    private Bitmap mBitmap;
    private BitmapShader mShader;
    private boolean mShowNotifyDot;
    private float mNotifyDotRadius;
    private float mNotifyDotBorderWidth;

    public CircularPhotoView(final Context context) {
        super(context);
        init();
    }

    public CircularPhotoView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.circularImageViewStyle);
    }

    public CircularPhotoView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.Bibi_CircularImageView, defStyle, 0);
        if (attributes.getBoolean(R.styleable.Bibi_CircularImageView_border, false)) {
            int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
            setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.Bibi_CircularImageView_border_width, defaultBorderSize));
            setBorderColor(attributes.getColor(R.styleable.Bibi_CircularImageView_border_color, Color.WHITE));
        }

        if (attributes.getBoolean(R.styleable.Bibi_CircularImageView_shadow, false))
            addShadow();

        attributes.recycle();
    }

    private void init() {
        // init paint
        mPaint = new Paint();
        mPaint.setAntiAlias(true);


        mNotifyDotPaint = new Paint();
        mNotifyDotPaint.setAntiAlias(true);
        mNotifyDotPaint.setColor(getContext().getResources().getColor(R.color.bibi_call_log_miss_call_red_dot));

        mNotifyDotBorderPaint = new Paint();
        mNotifyDotBorderPaint.setAntiAlias(true);
        mNotifyDotBorderPaint.setColor(getContext().getResources().getColor(R.color.bibi_application_bg));

        DisplayMetrics dm = getResources().getDisplayMetrics();
        mNotifyDotRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, dm);
        mNotifyDotBorderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, dm);

        mShowNotifyDot = false;
    }

    public void setShowNotifyDot(boolean showNotifyDot) {
        mShowNotifyDot = showNotifyDot;
    }

    public void setBorderWidth(int borderWidth) {
        this.mBorderWidth = borderWidth;
    }

    public void setBorderColor(int borderColor) {
        mPaintBorder = new Paint();
        mPaintBorder.setAntiAlias(true);
        mBorderWidth = DisplayUtils.px2dp(getContext(), 1);
        if (mPaintBorder != null) {
            mPaintBorder.setColor(borderColor);
        }
    }

    public void setBgColor(@ColorInt int bgColor) {
        if (bgColor != 0) {
            mPaintBg = new Paint();
            mPaintBg.setAntiAlias(true);
            if (mPaintBg != null) {
                mPaintBg.setColor(bgColor);
            }
        } else {
            mPaintBg = null;
        }

    }

    public void addShadow() {
        mPaintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    public void addShadow(float dx, float dy, float radius, int shadowColor) {
        if (mPaintBorder == null) {
            mPaintBorder = new Paint();
            mPaintBorder.setAntiAlias(true);
        }
        mPaintBorder.setShadowLayer(radius, dx, dy, shadowColor);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        mBitmap = drawableToBitmap(getDrawable());
        if (mBitmap != null && mCanvasSize > 0) {
            mShader = new BitmapShader(Bitmap.createScaledBitmap(mBitmap, mCanvasSize, mCanvasSize, false),
                    Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        }
    }

    @Override
    public void setImageBitmap(Bitmap image) {
        super.setImageBitmap(image);
        mBitmap = drawableToBitmap(getDrawable());
        if (mBitmap != null && mCanvasSize > 0) {
            mShader = new BitmapShader(Bitmap.createScaledBitmap(mBitmap, mCanvasSize, mCanvasSize, false),
                    Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        int radius = (mCanvasSize - (mBorderWidth * 2)) / 2;
        float centerX = mCanvasSize / 2;
        float centerY = mCanvasSize / 2;
        if (mPaintBorder != null) {
            canvas.drawCircle(centerX, centerY, radius + mBorderWidth, mPaintBorder);
        }
        if (mPaintBg != null) {
            canvas.drawCircle(centerX, centerY, radius, mPaintBg);
        }
        if (mShader != null && getDrawable() != null) {
            mPaint.setShader(mShader);
            canvas.drawCircle(centerX, centerY, radius, mPaint);
        }

        if (mShowNotifyDot) {
            float notifyDotCenterX = centerX + (float) (radius / Math.sqrt(2));
            float notifyDotCenterY = centerY - (float) (radius / Math.sqrt(2));
            canvas.drawCircle(notifyDotCenterX, notifyDotCenterY,
                    mNotifyDotRadius + mNotifyDotBorderWidth, mNotifyDotBorderPaint);
            canvas.drawCircle(notifyDotCenterX, notifyDotCenterY,
                    mNotifyDotRadius, mNotifyDotPaint);
        }
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        boolean sizeChanged = mCanvasSize != width;
        mCanvasSize = width;
        if (mBitmap != null && sizeChanged && width > 0) {
            mShader = new BitmapShader(Bitmap.createScaledBitmap(mBitmap, mCanvasSize, mCanvasSize, false),
                    Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        }
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        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 = mCanvasSize;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight) {
        int result = 0;
        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 = mCanvasSize;
        }

        return result;
    }

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

        Bitmap bitmap = null;

        if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
            bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
        } else {
            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 bitmap;
    }

}
 
 
 
一开始以为是ImageView 在哪个地方被重新设置值了,各种方法设置,
后来才发现,fuck,这个类的onDraw 方法被重写了,
并且重写之后也没有调用父类的onDraw方法。
 
 
在解这个bug的过程中发现,用glide 加载这个Image是可以的,
 
Glide.with(this).load(R.mipmap.ic_launcher).into(iv_main);

或许是因为Glide内部用的不是setImageResource方法,而是用的
setImageDrawable
或者
setImageBitmap
这两个方法吧,
这个bug困扰了我好几个小时,
因为一开始思路错了,
总以为这个ImageView在别的地方被别人重新set值了,
后来发现imageView.postDelay 了整整30秒,依然无效,
才发现是这个方法的问题
之前写这个类的人真是个坑货!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值