2
私は、無効化を呼び出すときにonDrawまたはdispatchDrawを呼び出さないカスタムビューを使用しています。Androidカスタムビュー、invalidate()を呼び出した後にonDrawが呼び出されない
私はsetWillNotDraw(false)を呼び出しました。この回答に記載されているようなコンストラクタではWhy onDraw is not called after invalidate()?
しかし、それでも何も変わらないが、onDrawは呼び出されない。
スーパービューでinvlidate()を呼び出そうとしましたが、まだ運がありません。
私は立ち往生しています、ご協力いただきありがとうございます。
package com.github.lzyzsd.circleprogress;
import common.utils.Debug;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by bruce on 14-10-30.
*/
public class DonutProgress extends View {
private Paint finishedPaint;
private Paint unfinishedPaint;
private Paint innerCirclePaint;
protected Paint textPaint;
protected Paint innerBottomTextPaint;
private RectF finishedOuterRect = new RectF();
private RectF unfinishedOuterRect = new RectF();
private float textSize;
private int textColor;
private int innerBottomTextColor;
private int progress = 0;
private int max;
private int finishedStrokeColor;
private int unfinishedStrokeColor;
private int startingDegree;
private float finishedStrokeWidth;
private float unfinishedStrokeWidth;
private int innerBackgroundColor;
private String prefixText = "";
private String suffixText = "%";
private String text = null;
private float innerBottomTextSize;
private String innerBottomText;
private float innerBottomTextHeight;
private final float default_stroke_width;
private final int default_finished_color = Color.rgb(66, 145, 241);
private final int default_unfinished_color = Color.rgb(204, 204, 204);
private final int default_text_color = Color.rgb(66, 145, 241);
private final int default_inner_bottom_text_color = Color.rgb(66, 145, 241);
private final int default_inner_background_color = Color.TRANSPARENT;
private final int default_max = 100;
private final int default_startingDegree = 0;
private final float default_text_size;
private final float default_inner_bottom_text_size;
private final int min_size;
private static final String INSTANCE_STATE = "saved_instance";
private static final String INSTANCE_TEXT_COLOR = "text_color";
private static final String INSTANCE_TEXT_SIZE = "text_size";
private static final String INSTANCE_TEXT = "text";
private static final String INSTANCE_INNER_BOTTOM_TEXT_SIZE = "inner_bottom_text_size";
private static final String INSTANCE_INNER_BOTTOM_TEXT = "inner_bottom_text";
private static final String INSTANCE_INNER_BOTTOM_TEXT_COLOR = "inner_bottom_text_color";
private static final String INSTANCE_FINISHED_STROKE_COLOR = "finished_stroke_color";
private static final String INSTANCE_UNFINISHED_STROKE_COLOR = "unfinished_stroke_color";
private static final String INSTANCE_MAX = "max";
private static final String INSTANCE_PROGRESS = "progress";
private static final String INSTANCE_SUFFIX = "suffix";
private static final String INSTANCE_PREFIX = "prefix";
private static final String INSTANCE_FINISHED_STROKE_WIDTH = "finished_stroke_width";
private static final String INSTANCE_UNFINISHED_STROKE_WIDTH = "unfinished_stroke_width";
private static final String INSTANCE_BACKGROUND_COLOR = "inner_background_color";
private static final String INSTANCE_STARTING_DEGREE = "starting_degree";
public DonutProgress(Context context) {
this(context, null);
}
public DonutProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DonutProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
default_text_size = Utils.sp2px(getResources(), 18);
min_size = (int) Utils.dp2px(getResources(), 100);
default_stroke_width = Utils.dp2px(getResources(), 10);
default_inner_bottom_text_size = Utils.sp2px(getResources(), 18);
/*
final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DonutProgress, defStyleAttr, 0);
initByAttributes(attributes);
attributes.recycle();
*/
initByAttributes(null);
setWillNotDraw(false);
initPainters();
}
protected void initPainters() {
textPaint = new TextPaint();
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
innerBottomTextPaint = new TextPaint();
innerBottomTextPaint.setColor(innerBottomTextColor);
innerBottomTextPaint.setTextSize(innerBottomTextSize);
innerBottomTextPaint.setAntiAlias(true);
finishedPaint = new Paint();
finishedPaint.setColor(finishedStrokeColor);
finishedPaint.setStyle(Paint.Style.STROKE);
finishedPaint.setAntiAlias(true);
finishedPaint.setStrokeWidth(finishedStrokeWidth);
unfinishedPaint = new Paint();
unfinishedPaint.setColor(unfinishedStrokeColor);
unfinishedPaint.setStyle(Paint.Style.STROKE);
unfinishedPaint.setAntiAlias(true);
unfinishedPaint.setStrokeWidth(unfinishedStrokeWidth);
innerCirclePaint = new Paint();
innerCirclePaint.setColor(innerBackgroundColor);
innerCirclePaint.setAntiAlias(true);
}
protected void initByAttributes(TypedArray attributes) {
finishedStrokeColor = default_finished_color;
unfinishedStrokeColor = default_unfinished_color;
textColor = default_text_color;
textSize = default_text_size;
setMax(default_max);
setProgress(0);
finishedStrokeWidth = default_stroke_width;
unfinishedStrokeWidth = default_stroke_width;
innerBackgroundColor = default_inner_background_color;
innerBottomTextSize = default_inner_bottom_text_size;
innerBottomTextColor = default_inner_bottom_text_color;
innerBottomText = "";
startingDegree = default_startingDegree;
}
@Override
public void invalidate() {
initPainters();
super.invalidate();
}
public float getFinishedStrokeWidth() {
return finishedStrokeWidth;
}
public void setFinishedStrokeWidth(float finishedStrokeWidth) {
this.finishedStrokeWidth = finishedStrokeWidth;
this.invalidate();
}
public float getUnfinishedStrokeWidth() {
return unfinishedStrokeWidth;
}
public void setUnfinishedStrokeWidth(float unfinishedStrokeWidth) {
this.unfinishedStrokeWidth = unfinishedStrokeWidth;
this.invalidate();
}
private float getProgressAngle() {
return getProgress()/(float) max * 360f;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
Debug.log("Donut", "progress="+progress);
if (this.progress > getMax()) {
this.progress %= getMax();
}
invalidate();
}
public int getMax() {
return max;
}
public void setMax(int max) {
if (max > 0) {
this.max = max;
invalidate();
}
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
this.invalidate();
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
this.invalidate();
}
public int getFinishedStrokeColor() {
return finishedStrokeColor;
}
public void setFinishedStrokeColor(int finishedStrokeColor) {
this.finishedStrokeColor = finishedStrokeColor;
this.invalidate();
}
public int getUnfinishedStrokeColor() {
return unfinishedStrokeColor;
}
public void setUnfinishedStrokeColor(int unfinishedStrokeColor) {
this.unfinishedStrokeColor = unfinishedStrokeColor;
this.invalidate();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
this.invalidate();
}
public String getSuffixText() {
return suffixText;
}
public void setSuffixText(String suffixText) {
this.suffixText = suffixText;
this.invalidate();
}
public String getPrefixText() {
return prefixText;
}
public void setPrefixText(String prefixText) {
this.prefixText = prefixText;
this.invalidate();
}
public int getInnerBackgroundColor() {
return innerBackgroundColor;
}
public void setInnerBackgroundColor(int innerBackgroundColor) {
this.innerBackgroundColor = innerBackgroundColor;
this.invalidate();
}
public String getInnerBottomText() {
return innerBottomText;
}
public void setInnerBottomText(String innerBottomText) {
this.innerBottomText = innerBottomText;
this.invalidate();
}
public float getInnerBottomTextSize() {
return innerBottomTextSize;
}
public void setInnerBottomTextSize(float innerBottomTextSize) {
this.innerBottomTextSize = innerBottomTextSize;
this.invalidate();
}
public int getInnerBottomTextColor() {
return innerBottomTextColor;
}
public void setInnerBottomTextColor(int innerBottomTextColor) {
this.innerBottomTextColor = innerBottomTextColor;
this.invalidate();
}
public int getStartingDegree() {
return startingDegree;
}
public void setStartingDegree(int startingDegree) {
this.startingDegree = startingDegree;
this.invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
//TODO calculate inner circle height and then position bottom text at the bottom (3/4)
innerBottomTextHeight = getHeight() - (getHeight()*3) /4 ;
}
private int measure(int measureSpec){
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if(mode == MeasureSpec.EXACTLY){
result = size;
}else{
result = min_size;
if(mode == MeasureSpec.AT_MOST){
result = Math.min(result, size);
}
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float delta = Math.max(finishedStrokeWidth, unfinishedStrokeWidth);
finishedOuterRect.set(delta,
delta,
getWidth() - delta,
getHeight() - delta);
unfinishedOuterRect.set(delta,
delta,
getWidth() - delta,
getHeight() - delta);
float innerCircleRadius = (getWidth() - Math.min(finishedStrokeWidth, unfinishedStrokeWidth) + Math.abs(finishedStrokeWidth - unfinishedStrokeWidth))/2f;
canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, innerCircleRadius, innerCirclePaint);
canvas.drawArc(finishedOuterRect, getStartingDegree(), getProgressAngle(), false, finishedPaint);
canvas.drawArc(unfinishedOuterRect, getStartingDegree() + getProgressAngle(), 360 - getProgressAngle(), false, unfinishedPaint);
String text = this.text != null ? this.text : prefixText + progress + suffixText;
if (!TextUtils.isEmpty(text)) {
float textHeight = textPaint.descent() + textPaint.ascent();
canvas.drawText(text, (getWidth() - textPaint.measureText(text))/2.0f, (getWidth() - textHeight)/2.0f, textPaint);
}
if (!TextUtils.isEmpty(getInnerBottomText())) {
innerBottomTextPaint.setTextSize(innerBottomTextSize);
float bottomTextBaseline = getHeight() - innerBottomTextHeight - (textPaint.descent() + textPaint.ascent())/2;
canvas.drawText(getInnerBottomText(), (getWidth() - innerBottomTextPaint.measureText(getInnerBottomText()))/2.0f, bottomTextBaseline, innerBottomTextPaint);
}
}
/*
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
float delta = Math.max(finishedStrokeWidth, unfinishedStrokeWidth);
finishedOuterRect.set(delta,
delta,
getWidth() - delta,
getHeight() - delta);
unfinishedOuterRect.set(delta,
delta,
getWidth() - delta,
getHeight() - delta);
float innerCircleRadius = (getWidth() - Math.min(finishedStrokeWidth, unfinishedStrokeWidth) + Math.abs(finishedStrokeWidth - unfinishedStrokeWidth))/2f;
canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, innerCircleRadius, innerCirclePaint);
canvas.drawArc(finishedOuterRect, getStartingDegree(), getProgressAngle(), false, finishedPaint);
canvas.drawArc(unfinishedOuterRect, getStartingDegree() + getProgressAngle(), 360 - getProgressAngle(), false, unfinishedPaint);
String text = this.text != null ? this.text : prefixText + progress + suffixText;
if (!TextUtils.isEmpty(text)) {
float textHeight = textPaint.descent() + textPaint.ascent();
canvas.drawText(text, (getWidth() - textPaint.measureText(text))/2.0f, (getWidth() - textHeight)/2.0f, textPaint);
}
if (!TextUtils.isEmpty(getInnerBottomText())) {
innerBottomTextPaint.setTextSize(innerBottomTextSize);
float bottomTextBaseline = getHeight() - innerBottomTextHeight - (textPaint.descent() + textPaint.ascent())/2;
canvas.drawText(getInnerBottomText(), (getWidth() - innerBottomTextPaint.measureText(getInnerBottomText()))/2.0f, bottomTextBaseline, innerBottomTextPaint);
}
}
*/
@Override
protected Parcelable onSaveInstanceState() {
final Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
bundle.putFloat(INSTANCE_TEXT_SIZE, getTextSize());
bundle.putFloat(INSTANCE_INNER_BOTTOM_TEXT_SIZE, getInnerBottomTextSize());
bundle.putFloat(INSTANCE_INNER_BOTTOM_TEXT_COLOR, getInnerBottomTextColor());
bundle.putString(INSTANCE_INNER_BOTTOM_TEXT, getInnerBottomText());
bundle.putInt(INSTANCE_INNER_BOTTOM_TEXT_COLOR, getInnerBottomTextColor());
bundle.putInt(INSTANCE_FINISHED_STROKE_COLOR, getFinishedStrokeColor());
bundle.putInt(INSTANCE_UNFINISHED_STROKE_COLOR, getUnfinishedStrokeColor());
bundle.putInt(INSTANCE_MAX, getMax());
bundle.putInt(INSTANCE_STARTING_DEGREE, getStartingDegree());
bundle.putInt(INSTANCE_PROGRESS, getProgress());
bundle.putString(INSTANCE_SUFFIX, getSuffixText());
bundle.putString(INSTANCE_PREFIX, getPrefixText());
bundle.putString(INSTANCE_TEXT, getText());
bundle.putFloat(INSTANCE_FINISHED_STROKE_WIDTH, getFinishedStrokeWidth());
bundle.putFloat(INSTANCE_UNFINISHED_STROKE_WIDTH, getUnfinishedStrokeWidth());
bundle.putInt(INSTANCE_BACKGROUND_COLOR, getInnerBackgroundColor());
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if(state instanceof Bundle) {
final Bundle bundle = (Bundle) state;
textColor = bundle.getInt(INSTANCE_TEXT_COLOR);
textSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
innerBottomTextSize = bundle.getFloat(INSTANCE_INNER_BOTTOM_TEXT_SIZE);
innerBottomText = bundle.getString(INSTANCE_INNER_BOTTOM_TEXT);
innerBottomTextColor = bundle.getInt(INSTANCE_INNER_BOTTOM_TEXT_COLOR);
finishedStrokeColor = bundle.getInt(INSTANCE_FINISHED_STROKE_COLOR);
unfinishedStrokeColor = bundle.getInt(INSTANCE_UNFINISHED_STROKE_COLOR);
finishedStrokeWidth = bundle.getFloat(INSTANCE_FINISHED_STROKE_WIDTH);
unfinishedStrokeWidth = bundle.getFloat(INSTANCE_UNFINISHED_STROKE_WIDTH);
innerBackgroundColor = bundle.getInt(INSTANCE_BACKGROUND_COLOR);
initPainters();
setMax(bundle.getInt(INSTANCE_MAX));
setStartingDegree(bundle.getInt(INSTANCE_STARTING_DEGREE));
setProgress(bundle.getInt(INSTANCE_PROGRESS));
prefixText = bundle.getString(INSTANCE_PREFIX);
suffixText = bundle.getString(INSTANCE_SUFFIX);
text = bundle.getString(INSTANCE_TEXT);
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
return;
}
super.onRestoreInstanceState(state);
}
}
ブラインドの推測:あなたは明らかに再描画するために「時間がない」OSとして動作しませんメインスレッド上でいくつかのループで 'DonutProgress.setProgress'を使用して、メイン(UI)スレッドとは...理解していません'setProgress'コールの間での表示 – Selvin
あなたは正しいです、私はちょうどrunOnUiThreadでsetProgressを呼び出し、それは働いた。 – jptsetung