CircleImageView分析

先把代码贴上。为了方便分析,所以有些System.out.println。

public class CircleImageView extends ImageView {

    private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 2;
    private static final int DEFAULT_BORDER_WIDTH = 0;
    private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
    private static final boolean DEFAULT_BORDER_OVERLAY = false;
    private final RectF mBorderRect = new RectF();
    private final RectF mDrawableRect = new RectF();
    private final Matrix mShaderMatrix = new Matrix();
    private final Paint mBitmapPaint = new Paint();
    private final Paint mBorderPaint = new Paint();
    private int mBorderColor = DEFAULT_BORDER_COLOR;
    private int mBorderWidth = DEFAULT_BORDER_WIDTH;
    private Bitmap mBitmap;
    private BitmapShader mBitmapShader;
    private int mBitmapHeight;
    private int mBitmapWidth;
    private float mDrawableRadius;
    private float mBorderRadius;
    private ColorFilter mColorFilter;
    private boolean mReady;
    private boolean mSetupPending;
    private boolean mBorderOverlay;

    public CircleImageView(Context context) {
        super(context);
        init();
        System.out.println("CircleImageView1");
    }

    public CircleImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        System.out.println("CircleImageView2");
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        System.out.println("CircleImageView3");
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyleAttr, 0);
        mBorderWidth = array.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
        mBorderColor = array.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
        mBorderOverlay = array.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);
        System.out.println("CircleImageView3.1");
        array.recycle();
        System.out.println("CircleImageView3.2");
        init();
        System.out.println("CircleImageView3.3");
    }

    private void init() {
        System.out.println("init1");
        super.setScaleType(SCALE_TYPE);
        System.out.println("init2");
        mReady = true;
        if (mSetupPending) {
            System.out.println("init+mSetupPending");
            setup();
            mSetupPending = false;
        }
        System.out.println("init3");
    }

    @Override
    public ScaleType getScaleType() {
        return SCALE_TYPE;
    }

    @Override
    public void setScaleType(ScaleType scaleType) {
        if (scaleType != SCALE_TYPE) {
            throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
        }
    }

    @Override
    public void setAdjustViewBounds(boolean adjustViewBounds) {
        if (adjustViewBounds) {
            throw new IllegalArgumentException("adjustViewBounds not supported.");
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        System.out.println("onDraw1");
        if (getDrawable() == null) {
            return;
        }
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
//        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 400, mBitmapPaint);
        if (mBorderWidth != 0) {
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
//            canvas.drawCircle(getWidth() / 2, getHeight() / 2, 400, mBorderPaint);
        }
        System.out.println("onDraw2");
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        System.out.println("onSizeChanged1");
        setup();
        System.out.println("onSizeChanged2");
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        System.out.println("setImageBitmap1");
        mBitmap = bm;
        System.out.println("setImageBitmap2");
        setup();
        System.out.println("setImageBitmap3");
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        System.out.println("onMeasure");
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        System.out.println("onLayout");
    }


    @Override
    public void setColorFilter(ColorFilter cf) {
        if (cf == mColorFilter) {
            return;
        }
        mColorFilter = cf;
        mBitmapPaint.setColorFilter(mColorFilter);
        invalidate();
    }

    private void setup() {
        System.out.println("setup1");
        if (!mReady) {
            System.out.println("mSetupPending = true;");
            mSetupPending = true;
            return;
        }
        System.out.println("setup2");
        if (mBitmap == null) {
            return;
        }
        System.out.println("setup3");
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setShader(mBitmapShader);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStrokeWidth(mBorderWidth);
        mBitmapHeight = mBitmap.getHeight();
        mBitmapWidth = mBitmap.getWidth();
        mBorderRect.set(0, 0, getWidth(), getHeight());
        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, ((mBorderRect.width() - mBorderWidth) / 2));
        mDrawableRect.set(mBorderRect);
        if (!mBorderOverlay) {
            mDrawableRect.inset(mBorderWidth, mBorderWidth);
        }
        mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
        System.out.println("setup4");
        updateShaderMatrix();
        System.out.println("setup5");
        invalidate();
        System.out.println("setup6");
    }

    @Override
    public void invalidate() {
        super.invalidate();
        System.out.println("invalidate");
    }

    public void updateShaderMatrix() {
        System.out.println("updateShaderMatrix1");
        float scale;
        float dx = 0;
        float dy = 0;
        mShaderMatrix.set(null);
        if (mBitmapWidth * mDrawableRect.height() > mBitmapHeight * mDrawableRect.width()) {
            scale = mDrawableRect.height() / (float) mBitmapHeight;
            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
        } else {
            scale = mDrawableRect.width() / (float) mBitmapWidth;
            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
        }
        System.out.println("mShaderMatrix.setScale(scale, scale)");
        mShaderMatrix.setScale(scale, scale);
        System.out.println("mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top)");
        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
        System.out.println("mBitmapShader.setLocalMatrix(mShaderMatrix)");
        mBitmapShader.setLocalMatrix(mShaderMatrix);
        System.out.println("updateShaderMatrix2");
    }
}

用的是setImageBitmap,下面是输出结果:

09-07 14:11:50.176 13540-13540/com.example.myselfimageview I/System.out: CircleImageView3
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: CircleImageView3.1
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: CircleImageView3.2
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: init1
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: invalidate
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: init2
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: init3
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: CircleImageView3.3
09-07 14:11:50.177 13540-13540/com.example.myselfimageview I/System.out: CircleImageView2
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: invalidate
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setImageBitmap1
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setImageBitmap2
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setup1
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setup2
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setup3
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setup4
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: updateShaderMatrix1
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: mShaderMatrix.setScale(scale, scale)
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top)
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: mBitmapShader.setLocalMatrix(mShaderMatrix)
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: updateShaderMatrix2
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: setup5
09-07 14:11:50.412 13540-13540/com.example.myselfimageview I/System.out: invalidate
09-07 14:11:50.413 13540-13540/com.example.myselfimageview I/System.out: setup6
09-07 14:11:50.413 13540-13540/com.example.myselfimageview I/System.out: setImageBitmap3
09-07 14:11:50.451 13540-13540/com.example.myselfimageview I/System.out: onMeasure
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: onSizeChanged1
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup1
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup2
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup3
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup4
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: updateShaderMatrix1
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: mShaderMatrix.setScale(scale, scale)
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top)
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: mBitmapShader.setLocalMatrix(mShaderMatrix)
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: updateShaderMatrix2
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup5
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: invalidate
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: setup6
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: onSizeChanged2
09-07 14:11:50.467 13540-13540/com.example.myselfimageview I/System.out: onLayout
09-07 14:11:50.474 13540-13573/com.example.myselfimageview E/GED: Failed to get GED Log Buf, err(0)
09-07 14:11:50.476 13540-13573/com.example.myselfimageview I/OpenGLRenderer: Initialized EGL, version 1.4
09-07 14:11:50.476 13540-13573/com.example.myselfimageview W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
09-07 14:11:50.480 13540-13573/com.example.myselfimageview I/OpenGLRenderer: Initializing program atlas...
09-07 14:11:50.495 13540-13540/com.example.myselfimageview I/System.out: onMeasure
09-07 14:11:50.495 13540-13540/com.example.myselfimageview I/System.out: onLayout
09-07 14:11:50.496 13540-13540/com.example.myselfimageview I/System.out: onDraw1
09-07 14:11:50.496 13540-13540/com.example.myselfimageview I/System.out: onDraw2

根据输出结果,一开始进入的是这个方法:

    public CircleImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        System.out.println("CircleImageView2");
    }

这里this(context, attrs, 0);表示的是调用public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr){......}这个方法。

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        System.out.println("CircleImageView3");
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyleAttr, 0);
        mBorderWidth = array.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
        mBorderColor = array.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
        mBorderOverlay = array.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);
        System.out.println("CircleImageView3.1");
        array.recycle();
        System.out.println("CircleImageView3.2");
        init();
        System.out.println("CircleImageView3.3");
    }

运行到了init();就进入了private void init(){.......};方法:

    private void init() {
        System.out.println("init1");
        super.setScaleType(SCALE_TYPE);
        System.out.println("init2");
        mReady = true;
        if (mSetupPending) {
            System.out.println("init+mSetupPending");
            setup();
            mSetupPending = false;
        }
        System.out.println("init3");
    }

运行到super.setScaleType(SCALE_TYPE);时,触发了invalidate。紧接着往下运行,给mReady赋值为true。但是因为mSetupPending是false,所以没能进入if模块,而是直接结束init方法。

private void init(){.......};方法运行 结束后,public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr){......}该方法也结束了。然后回到public CircleImageView(Context context, AttributeSet attrs){......}方法,结束本方法,然后触发了invalidate方法 。

然后执行的是继承了ImageView后重写的setImageBitmap方法

    @Override
        public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        System.out.println("setImageBitmap1");
        mBitmap = bm;
        System.out.println("setImageBitmap2");
        setup();
        System.out.println("setImageBitmap3");
    }

可以看到setImageBitmap内的方法执行到了setup的时候,进入了setup方法。

private void setup() {
        System.out.println("setup1");
        if (!mReady) {
            System.out.println("mSetupPending = true;");
            mSetupPending = true;
            return;
        }
        System.out.println("setup2");
        if (mBitmap == null) {
            return;
        }
        System.out.println("setup3");
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setShader(mBitmapShader);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStrokeWidth(mBorderWidth);
        mBitmapHeight = mBitmap.getHeight();
        mBitmapWidth = mBitmap.getWidth();
        mBorderRect.set(0, 0, getWidth(), getHeight());
        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, ((mBorderRect.width() - mBorderWidth) / 2));
        mDrawableRect.set(mBorderRect);
        if (!mBorderOverlay) {
            mDrawableRect.inset(mBorderWidth, mBorderWidth);
        }
        mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
        System.out.println("setup4");
        updateShaderMatrix();
        System.out.println("setup5");
        invalidate();
        System.out.println("setup6");
    }

setup方法执行到updateShaderMatrix();时,又进入了updateShaderMatrix方法。

public void updateShaderMatrix() {
        System.out.println("updateShaderMatrix1");
        float scale;
        float dx = 0;
        float dy = 0;
        mShaderMatrix.set(null);
        if (mBitmapWidth * mDrawableRect.height() > mBitmapHeight * mDrawableRect.width()) {
            scale = mDrawableRect.height() / (float) mBitmapHeight;
            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
        } else {
            scale = mDrawableRect.width() / (float) mBitmapWidth;
            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
        }
        System.out.println("mShaderMatrix.setScale(scale, scale)");
        mShaderMatrix.setScale(scale, scale);
        System.out.println("mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top)");
        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
        System.out.println("mBitmapShader.setLocalMatrix(mShaderMatrix)");
        mBitmapShader.setLocalMatrix(mShaderMatrix);
        System.out.println("updateShaderMatrix2");
    }

在整一个updateShaderMatrix方法执行完后,回到setup方法继续往下执行,触发了invalidate方法,然后结束setup方法。然后回到setImageBitmap方法,结束setImageBitmap方法,然后进行onMeasure方法。而后进入onSizeChanged方法,调用了父类的super.onSizeChanged(w, h, oldw, oldh);后,进入setup方法。当执行到updateShaderMatrix();时候,又进入了updateShaderMatrix();方法。updateShaderMatrix();整一个方法块运行结束后,回到setup方法,结束setup方法。然后回到onSizeChanged方法,结束onSizeChanged方法,进行onLayout

然后再进行一次onMeasureonLayout验证,然后进行ondraw

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值