2016-04-11 7 views
2

Ich benutze eine benutzerdefinierte Ansicht, die onDraw nicht aufrufen, oder dispatchDraw, wenn ich Ungültigkeit aufrufen.Android benutzerdefinierte Ansicht, onDraw nicht nach dem Aufruf von invalidate() aufgerufen

Ich rief setWillNotDraw (false); im Konstruktor wie in dieser Antwort gesagt Why onDraw is not called after invalidate()?

Aber das ändert nichts, noch onDraw wird nicht aufgerufen.

Ich versuchte Invlidate() auf der Super-View, aber immer noch kein Glück zu nennen.

Ich stecke fest, danke für Ihre Hilfe.

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); 
    } 
} 
+0

blinder Vermutung: Sie verstehen nicht die Haupt (UI) Faden und 'DonutProgress.setProgress' in irgendeiner Schleife auf Hauptthread mit ... was natürlich nicht als OS„keine Zeit hat,“wird sich die neu zu zeichnen Blick zwischen 'setProgress' Anrufe – Selvin

+0

Thx Sie hatten Recht, ich rief gerade setProgress in runOnUiThread, und es hat funktioniert. – jptsetung

Antwort

0

Der Aufruf von SetProgress wurde in einer Timer-Schleife durchgeführt, die nicht der UI-Thread ist. Ich habe runOnUiThread so verwendet, damit es funktioniert.

MyActivity.this.runOnUiThread(new Runnable() { 
     public void run() { 
       mProgress.setProgress(0); 
     } 
}); 
Verwandte Themen