2016-04-11 2 views
2

J'utilise une vue personnalisée qui n'appelle pas onDraw, ou dispatchDraw lorsque j'appelle invalate.Affichage personnalisé Android, onDraw non appelé après avoir appelé invalidate()

J'ai appelé setWillNotDraw (false); dans le constructeur comme indiqué dans cette réponse Why onDraw is not called after invalidate()?

Mais cela ne change rien, toujours onDraw n'est pas appelé.

J'ai essayé d'appeler invlidate() sur la super vue, mais toujours pas de chance.

Je suis coincé, merci pour votre aide.

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

conjecture aveugle: vous ne comprenez pas le principal (UI) fil et en utilisant 'DonutProgress.setProgress' dans une boucle sur fil conducteur ... qui fonctionne évidemment pas OS « n'a pas le temps » pour redessiner la vue entre les appels 'setProgress' – Selvin

+0

Thx vous aviez raison, je viens d'appeler setProgress dans runOnUiThread, et cela a fonctionné. – jptsetung

Répondre

0

L'appel à setProgress a été effectué dans une boucle de minuteur, qui n'est pas le thread ui. J'ai utilisé runOnUiThread comme ça pour le faire fonctionner.

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