2012-04-25 7 views
1

私のアプリケーションのカスタムビューがあり、OnDrawが呼び出されるたびにテキストを更新しようとしています。OnDrawでcanvas.drawTextでテキストを更新するには? Android

(の一部)は、私のコードは次のようにlookes:それはOnDrawで同じregenerateBackgroundによって呼び出されるがままだとき

@Override 
protected void onDraw(Canvas canvas) { 
    Log.e(TAG,"onDraw"); 
    drawBackground(canvas); 

    float scale = (float) getWidth();  
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.scale(scale, scale); 


    drawTitle(canvas); 
    drawHand(canvas); 


    canvas.restore(); 

    if (handNeedsToMove()) { 
     moveHand(); 
    } 
} 

private void drawTitle(Canvas canvas) { 

    String title = getTitle(); 
    Log.i("drawtitle",title); 

    titlePaint = new Paint(); 
    titlePaint.setColor(0xffffffff); 
    titlePaint.setAntiAlias(true); 
    titlePaint.setTypeface(Typeface.MONOSPACE); 
    titlePaint.setTextAlign(Paint.Align.CENTER); 
    titlePaint.setTextSize(0.05f); 
    titlePaint.setTextScaleX(0.8f); 

    canvas.drawText(title, 0.45f, 0.95f, titlePaint); 
} 
@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    Log.d(TAG, "Size changed to " + w + "x" + h); 

    regenerateBackground(); 
} 
private void regenerateBackground() { 
    if (background != null) { 
     background.recycle(); 
    } 

     //Some stuff here 

    drawInstruments(backgroundCanvas); 
    drawTitle(backgroundCanvas); 

} 

テキストが更新されます。どうして?直し方? Mabyにはcanvas.drawTextを使うよりも良い方法がありますか?私はスピードメーターを作っていると私はちょうど「針」を指しているその値を印刷したい...

編集:完全なコード

パブリック最終クラスダッシュボードは、ビュー{

private static final String TAG = Dashboard.class.getSimpleName(); 

// drawing tools 
private Paint dashPaint; 
private static Bitmap dash; 
private Matrix dashMatrix; 
private float dashScalex; 
private float dashScaley; 

private Paint handPaint; 
private Path handPath; 
private Paint handScrewPaint; 

private Paint backgroundPaint; 
// end drawing tools 

private Bitmap background; // holds the cached static part 


private Paint titlePaint; 
private Path titlePath; 

// scale configuration 
private static final int totalNicks = 100; 
private static final float degreesPerNick = 360.0f/totalNicks;  
private static final int centerDegree = 40; // the one in the top center (12 o'clock) 
private static final int minDegrees = -30; 
private static final int maxDegrees = 110; 

// hand dynamics -- all are angular expressed in F degrees 
private boolean handInitialized = true; 
private float handPosition = centerDegree; 
private float handTarget = centerDegree; 
private float handVelocity = 0.0f; 
private float handAcceleration = 0.0f; 
private long lastHandMoveTime = -1L; 

private static float circlePosx = 0.5f; 
private static float circlePosy = 0.36f; 
private static float circleRadius = 0.1f; 

public Dashboard(Context context) { 
    super(context); 
    init(); 
} 

public Dashboard(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 

public Dashboard(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
} 

@Override 
protected void onRestoreInstanceState(Parcelable state) { 
    Bundle bundle = (Bundle) state; 
    Parcelable superState = bundle.getParcelable("superState"); 
    super.onRestoreInstanceState(superState); 

    handInitialized = bundle.getBoolean("handInitialized"); 
    handPosition = bundle.getFloat("handPosition"); 
    handTarget = bundle.getFloat("handTarget"); 
    handVelocity = bundle.getFloat("handVelocity"); 
    handAcceleration = bundle.getFloat("handAcceleration"); 
    lastHandMoveTime = bundle.getLong("lastHandMoveTime"); 
} 

@Override 
protected Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 

    Bundle state = new Bundle(); 
    state.putParcelable("superState", superState); 
    state.putBoolean("handInitialized", handInitialized); 
    state.putFloat("handPosition", handPosition); 
    state.putFloat("handTarget", handTarget); 
    state.putFloat("handVelocity", handVelocity); 
    state.putFloat("handAcceleration", handAcceleration); 
    state.putLong("lastHandMoveTime", lastHandMoveTime); 
    return state; 
} 

public static float[] getCircle(){  
    float[] circle = {circlePosx,circlePosy,circleRadius}; 
    return circle; 
} 

public static int[] getCanvasSize(){ 
    int[] size = {dash.getWidth(),dash.getHeight()}; 
    return size; 
} 

private void init() { 
    initDrawingTools(); 
} 

private void initDrawingTools() { 

    /******/ 
    dashPaint = new Paint(); 
    dashPaint.setFilterBitmap(true); 
    dash = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.dashboard); 
    dashMatrix = new Matrix(); 


    dashScaley = 1f/dash.getHeight();// * 0.3f;; 
    dashScalex = 1f/dash.getWidth(); 
    dashMatrix.setScale(dashScalex, dashScaley);  

    Log.i("dash width", "= "+dash.getWidth()+" - "+getWidth()); 
    Log.i("dash height", "= "+dash.getHeight()); 
    Log.i("dash scale x ", "= "+1f/dash.getHeight()); 
    Log.i("dash scale y ", "= "+dashScaley); 

    /******/ 

    handPaint = new Paint(); 
    handPaint.setAntiAlias(true); 
    handPaint.setColor(0xffff0000);  
    handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000); 
    handPaint.setStyle(Paint.Style.FILL); 



    handPath = new Path(); 
    handPath.moveTo(circlePosx-0.01f, circlePosy+0.06f); 

    handPath.lineTo(circlePosx, circlePosy - 0.16f); 
    handPath.lineTo(circlePosx+0.01f, circlePosy + 0.06f); 
    handPath.addCircle(circlePosx, circlePosy, 0.025f, Path.Direction.CW); 

    handScrewPaint = new Paint(); 
    handScrewPaint.setAntiAlias(true); 
    handScrewPaint.setColor(0xf0000021); 
    handScrewPaint.setStyle(Paint.Style.FILL); 

    backgroundPaint = new Paint(); 
    backgroundPaint.setFilterBitmap(true); 

    titlePaint = new Paint(); 
    titlePaint.setColor(0xffffffff); 
    titlePaint.setAntiAlias(true); 
    titlePaint.setTypeface(Typeface.DEFAULT_BOLD); 
    titlePaint.setTextAlign(Paint.Align.CENTER); 
    titlePaint.setTextSize(0.05f); 
    titlePaint.setTextScaleX(0.8f); 


    titlePath = new Path(); 
    titlePath.moveTo(0.5f, 0.8f); 
    titlePath.lineTo(0.6f, 0.8f); 
    //titlePath = new Path(); 
    //titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f, -180.0f);   

} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec)); 
    Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec)); 

    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 

    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    int chosenWidth = chooseDimension(widthMode, widthSize); 
    int chosenHeight = chooseDimension(heightMode, heightSize); 


    setMeasuredDimension(chosenWidth, chosenHeight); 

    //int chosenDimension = Math.min(chosenWidth, chosenHeight); 
    //setMeasuredDimension(chosenDimension, chosenDimension); 
} 

private int chooseDimension(int mode, int size) { 
    if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { 
     return size; 
    } else { // (mode == MeasureSpec.UNSPECIFIED) 
     return getPreferredSize(); 
    } 
} 

// in case there is no size specified 
private int getPreferredSize() { 
    return 600; 
} 



private int nickToDegree(int nick) { 
    int rawDegree = ((nick < totalNicks/2) ? nick : (nick - totalNicks)) * 2; 
    int shiftedDegree = rawDegree + centerDegree; 
    return shiftedDegree; 
} 

private float degreeToAngle(float degree) { 
    return (degree - centerDegree)/2.0f * degreesPerNick; 
} 

private void drawInstruments(Canvas canvas){ 
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 

    canvas.translate(0.5f - dash.getWidth() * dashScalex/2.0f, 
        0.5f - dash.getHeight() * dashScaley/2.0f); 

    //canvas.drawBitmap(dash, 0, 0, dashPaint); 
    canvas.drawBitmap(dash, dashMatrix, dashPaint); 
    canvas.restore();   
} 

private void drawHand(Canvas canvas) { 
    Log.e(TAG, "drawHand"); 
    if (handInitialized) { 

     float handAngle = degreeToAngle(handPosition); 
     canvas.save(Canvas.MATRIX_SAVE_FLAG); 
     canvas.rotate(handAngle, circlePosx, circlePosy); 
     canvas.drawPath(handPath, handPaint); 
     canvas.restore(); 

     canvas.drawCircle(0.5f, 0.36f, 0.01f, handScrewPaint); 

    } 
} 
private String getTitle(){ 
    return String.valueOf(handPosition); 
} 
private void drawTitle(Canvas canvas) { 

    String title = getTitle(); 
    //canvas.drawTextOnPath(title, titlePath, 0.0f,0.0f, titlePaint); 
    //canvas.drawPaint(titlePaint); 

    Log.i("drawtitle",title); 

    canvas.drawText(title, 0.45f, 0.95f, titlePaint); 
    //invalidate(); 
} 


private void drawBackground(Canvas canvas) { 
    if (background == null) { 
     Log.w(TAG, "Background not created"); 
    } else { 
     canvas.drawBitmap(background, 0, 0, backgroundPaint); 
    } 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    Log.e(TAG,"onDraw"); 
    drawBackground(canvas); 

    float scale = (float) getWidth();  
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.scale(scale, scale); 


    drawTitle(canvas); 
    drawHand(canvas); 


    canvas.restore(); 

    if (handNeedsToMove()) { 
     moveHand(); 
    } 
} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    Log.d(TAG, "Size changed to " + w + "x" + h); 

    regenerateBackground(); 
} 

private void regenerateBackground() { 
    // free the old bitmap 
    if (background != null) { 
     background.recycle(); 
    } 


    Log.e("Width="+getWidth(), "Height="+getHeight()); 
    background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
    Canvas backgroundCanvas = new Canvas(background); 

    float scalex = (float) getWidth(); 
    float scaley = (float) getHeight(); 
    backgroundCanvas.scale(scalex, scaley); 

    drawInstruments(backgroundCanvas); 

} 

private boolean handNeedsToMove() { 
    return Math.abs(handPosition - handTarget) > 0.01f; 
} 

private void moveHand() { 
    Log.e(TAG, "moveHand!!"); 
    if (! handNeedsToMove()) { 
     return; 
    } 

    if (lastHandMoveTime != -1L) { 
     long currentTime = System.currentTimeMillis(); 
     float delta = (currentTime - lastHandMoveTime)/1000.0f; 

     float direction = Math.signum(handVelocity); 
     if (Math.abs(handVelocity) < 90.0f) { 
      handAcceleration = 5.0f * (handTarget - handPosition); 
     } else { 
      handAcceleration = 0.0f; 
     } 
     handPosition += handVelocity * delta; 
     handVelocity += handAcceleration * delta; 
     if ((handTarget - handPosition) * direction < 0.01f * direction) { 
      handPosition = handTarget; 
      handVelocity = 0.0f; 
      handAcceleration = 0.0f; 
      lastHandMoveTime = -1L; 
     } else { 
      lastHandMoveTime = System.currentTimeMillis();    
     } 
     invalidate(); 
    } else { 
     lastHandMoveTime = System.currentTimeMillis(); 
     moveHand(); 
    } 
} 


private float getRelativeTemperaturePosition() { 
    if (handPosition < centerDegree) { 
     return - (centerDegree - handPosition)/(float) (centerDegree - minDegrees); 
    } else { 
     return (handPosition - centerDegree)/(float) (maxDegrees - centerDegree); 
    } 
} 

public void setHandTarget(float temperature) { 
    Log.e(TAG, "setHandTarget!"); 
    if (temperature < minDegrees) { 
     temperature = minDegrees; 
    } else if (temperature > maxDegrees) { 
     temperature = maxDegrees; 
    } 
    handTarget = temperature; 
    Log.e(TAG, "handTarget="+handTarget); 
    handInitialized = true; 
    invalidate(); 
} 

public float getHandTarget(){ 
    return handTarget; 
} 
を拡張します

}

答えて

1

drawTitle()への呼び出しをregenerateBackground()から削除し、setTitle()メソッド内でinvalidateを呼び出します。

+0

これは、ビューを常時再生する(何も印刷しない)ことです。 drawHandの内部を無効にする呼び出しがあります。 – daker

+0

他の提案はありますか? :) – daker

+0

私の推測では、タイトルは定期的に更新したいテキストです。 invalidateを呼び出すと、onDrawがトリガーされます。タイトルが変更された場合は再描画する必要があるので、setTitle()はinvalidateを呼び出す場所です。また、タイトルが頻繁に変更されるので、背景イメージの一部であってはなりません。それで、あなたはそれをregenerateBackrgound()から削除する必要があります。 drawHand()でinvalidateを呼び出すと、無限のonDraw-> invalidateサイクルを作成しました – Renard

関連する問題