Android draw onAttachToWindow

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/izzxacbbt/article/details/84404350
package zzx.lly.custom_view.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import zzx.lly.custom_view.R;

public class Change_view extends View {
    //process determine the stage of this view that should be draw
    private int process;
    private Paint mPaint1;
    private int colorBegin;
    private int colorEnd=0;

    //在java代码则调用该构造方法
    public Change_view(Context context) {
        super(context);
        init();
    }

    //在xml调用时调用
    public Change_view(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    //不会自动调用,一般是在第二个构造方法里面主动调用,如view有style属性时候
    public Change_view(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Change_view);
        colorBegin = a.getColor(R.styleable.Change_view_circle_color, Color.RED);
        a.recycle();
        colorEnd=colorBegin;
        init();
    }

    public Change_view(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private void init() {
        mPaint1 = new Paint();
        mPaint1.setColor(colorEnd);
        mPaint1.setStrokeWidth(5f);
        mPaint1.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint1.setColor(colorEnd);
        int width = getWidth();
        int height = getHeight();
        int r = Math.min(width, height) / 2;
        canvas.drawCircle(width / 2, height / 2, r, mPaint1);
        Log.e("E", "draw");
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int mWidth = 400;
        int mHeight = 400;
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mWidth, mHeight);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mWidth, heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSize, mHeight);
        }
    }

    //接下来实现异步变换颜色,1,通过Async或者rxjava
    class ColorChangeAsycTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            colorEnd=colorBegin;
        }
        @Override //Result               params
        protected Void doInBackground(Void... voids) {
            while(true){
                colorEnd-=20;
                Log.e("E","colorChange");
                if (colorEnd <= colorBegin/2) {
                    colorEnd=colorBegin;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress();
            }
        }

        @Override                    //Result
        protected void onPostExecute(Void m) {
            super.onPostExecute(m);
        }

        @Override                       //progress
        protected void onProgressUpdate(Void... m) {
            invalidate();
        }
    }

    @Override//为了避免错误,我们在这里将Async new出来并实现,因为在构造方法中界面不一定初始完成
    protected void onAttachedToWindow() {
        Log.e("E", "beforeOnAttach");
        super.onAttachedToWindow();
        Log.e("E", "AfterOnAttach");
        new ColorChangeAsycTask().execute();
        Log.e("E", "onAttach");
    }
}


Log日志 |11-23 21:53:24.263 11194-11194/zzx.lly.custom_view E/E:
beforeOnAttach
AfterOnAttach 11-23 21:53:24.265 11194-11194/zzx.lly.custom_view E/E: onAttach 11-23 21:53:24.266 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.276 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.286 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.297 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.303 11194-11219/zzx.lly.custom_view E/GED:
Failed to get GED Log Buf, err(0) 11-23 21:53:24.307
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.317
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.328
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.331
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.338
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.348
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.358
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.369
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.379
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.389
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.400
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.410
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.417
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.420
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.428
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.431
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.441
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.445
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.451
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.461
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.462
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.472
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.478
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.482
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.493
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.494
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.503
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.511
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.513
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.524
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.527
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.534
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.544
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.544
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.555
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.560
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.565
11194-11220/zzx.lly.custom_view E/E: colorChange

问题是什么?

我们知道onAttachToWindow(以下简称ATW)发生在view被添加到屏幕,这个过程在是onResume之后,draw之前,所以我们这里可以看到先被打印的是关于ATW的内容,ATW开启异步改变颜色的线程,问题在于我们看到本来应当是打印一次colorChange会发生一次invalidate,invalidate应当要调用ondraw,但是显然,这里在一开始的时候,出现了多次colorChange,说明在ATW之后相当长的一段时间内,ondraw都不能被调用.当然后面有出现一两个colorChange对应一个ondraw的情况,这是因为我们的子线程速度太快了,如果sleep时间稍微长一点就不会出现这种情况了.
尝试一下

  colorEnd-=20;
                Log.e("E","colorChange");
                if (colorEnd <= colorBegin/2) {
                    colorEnd=colorBegin;
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

我们在这里将原本10毫秒休息一次改为50毫秒休息一次,然后再看日志,可以看到,现在一开始不响应的colorChange少了(这是因为子线程运行次数减少),并且一次colorChange一定有一次draw响应,符合预期.

11-23 22:06:23.717 12076-12076/zzx.lly.custom_view E/E: beforeOnAttach
AfterOnAttach 11-23 22:06:23.720 12076-12076/zzx.lly.custom_view E/E: onAttach 11-23 22:06:23.722 12076-12256/zzx.lly.custom_view E/E:
colorChange 11-23 22:06:23.774 12076-12256/zzx.lly.custom_view E/E:
colorChange 11-23 22:06:23.780 12076-12255/zzx.lly.custom_view E/GED:
Failed to get GED Log Buf, err(0) 11-23 22:06:23.824
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.839
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:23.877
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.928
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.978
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.009
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.028
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.033
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.049
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.079
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.096
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.129
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.146
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.180
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.195
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.230
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.245
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.281
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.294
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.331
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.344
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.381
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.393
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.432
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.442
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.482
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.492
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.532
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.541
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.583
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.591
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.633
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.641
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.685
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.691
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.736
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.740
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.788
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.789
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.840
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.855
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.892
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.904
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.944
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.954
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.994
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.004
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.046
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.053
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.097
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.111
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.148
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.152
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.201
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.202
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.253
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.268
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.305
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.317
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.356
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.367
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.409
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.416
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.466
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.482
12076-12076/zzx.lly.custom_view E/E: draw

总结

我们这里其实要实现这个效果不应当在ATW开启,而是应当在onDraw中进行一个判断,如果是第一次draw则开启子线程.另外使用Async也很麻烦,在实际中可以用rxjava代替

猜你喜欢

转载自blog.csdn.net/izzxacbbt/article/details/84404350