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代替