2016-04-11 38 views
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); 
    } 
} 
+0

ブラインドの推測:あなたは明らかに再描画するために「時間がない」OSとして動作しませんメインスレッド上でいくつかのループで 'DonutProgress.setProgress'を使用して、メイン(UI)スレッドとは...理解していません'setProgress'コールの間での表示 – Selvin

+0

あなたは正しいです、私はちょうどrunOnUiThreadでsetProgressを呼び出し、それは働いた。 – jptsetung

答えて

0

setProgressの呼び出しは、タイマループで実行されましたが、これはuiスレッドではありません。私はこのようにrunOnUiThreadを使って動作させました。

MyActivity.this.runOnUiThread(new Runnable() { 
     public void run() { 
       mProgress.setProgress(0); 
     } 
}); 
関連する問題