2011-09-28 66 views
3

我想畫在畫布上使用畫圖上的文字,我似乎無法弄清楚正確的X和Y給它。如果我記錄了getWidth和getHeight,我可以看到View實際上給出了旋轉畫布的寬度和高度。因此,它的東西就像20 X 240.我的東西很接近,但我只想讓文字垂直和水平居中。用於在(旋轉)畫布上繪製文本的x和y座標?

關於如何做到這一點的任何想法?

下面是它看起來像現在:

​​

這裏是我的代碼:

public class VerticalText extends View { 

    private Paint mTextPaint; 
    private String mText; 
    private int mAscent; 


    public ListLabelView(Context context) { 
     super(context); 
     initListLabel(); 
     this.setBackgroundColor(Color.BLUE); 
    } 

    private final void initListLabel() { 

     mTextPaint = new Paint(); 
     mTextPaint.setStyle(Paint.Style.FILL); 
     mTextPaint.setAntiAlias(true); 
     mTextPaint.setTextSize(12); 
     mTextPaint.setColor(Color.WHITE); 

     setPadding(3, 3, 3, 3); 
     invalidate(); 

    } 

    /** 
    * sets the text to display in this label 
    * @param text 
    */ 
    public void setText(String text) { 
     mText = text; 
     requestLayout(); 
     invalidate(); 
    } 

    /** 
    * sets the text color for this label 
    * @param color 
    */ 
    public void setTextColor(int color) { 
     mTextPaint.setColor(color); 
     invalidate(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     setMeasuredDimension(measureHeight(widthMeasureSpec), measureWidth(heightMeasureSpec)); 

    } 

    /** 
    * Determines the width of this view 
    * @param measureSpec A measureSpec packed into an int 
    * @return The width of the view, honoring constraints from measureSpec 
    */ 
    private int measureWidth(int measureSpec) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     if (specMode == MeasureSpec.EXACTLY) { 
      // We were told how big to be 
      result = specSize; 
     } else { 
      // Measure the text 
      result = (int) mTextPaint.measureText(mText) + getPaddingLeft() 
        + getPaddingRight(); 
      if (specMode == MeasureSpec.AT_MOST) { 
       // Respect AT_MOST value if that was what is called for by measureSpec 
       result = Math.min(result, specSize); 
      } 
     } 

     return result; 
    } 

    /** 
    * Determines the height of this view 
    * @param measureSpec A measureSpec packed into an int 
    * @return The height of the view, honoring constraints from measureSpec 
    */ 
    private int measureHeight(int measureSpec) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     mAscent = (int) mTextPaint.ascent(); 
     if (specMode == MeasureSpec.EXACTLY) { 
      // We were told how big to be 
      result = specSize; 
     } else { 
      // Measure the text (beware: ascent is a negative number) 
      result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() 
        + getPaddingBottom(); 
      if (specMode == MeasureSpec.AT_MOST) { 
       // Respect AT_MOST value if that was what is called for by measureSpec 
       result = Math.min(result, specSize); 
      } 
     } 
     return result; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     canvas.rotate(-90, getWidth()/2, getHeight()/2); 
// 
     mTextPaint.measureText(mText); 

     Log.v("width x height:", getWidth() + " X " + getHeight()); 

     canvas.drawText(mText, (getWidth() - (getWidth())) - 50, getHeight()/2, mTextPaint); 

     super.onDraw(canvas); 



    } 
} 

回答

4

我面臨同樣的問題。下面是我工作:

Rect tb = new Rect(); 
mTextPaint.getTextBounds(mText, 0, mText.length(), tb); 
canvas.drawText(mText, getWidth()/2f, getHeight()/2f + Math.abs(tb.top)/2f, mTextPaint); 

您的文本應居中:

mTextPaint.setTextAlign(Align.CENTER); 
+0

完美!所以getTextBounds基本上把這些邊界交給了矩形? – LuxuryMode

+0

沒錯。測量字符串的整個範圍可能有點矯枉過正,但它起作用;-)但是有時候返回的值會令人困惑(但我從來沒有失敗過,當我自己繪製文本時,只有當我試圖在TextView中破解我)。當文本礦石大小發生變化時,您可以對其進行一次測量,以避免在每次繪製時重新計算。 – Knickedi

+0

這將適用於所有形狀?我需要號碼被圈子包圍。 – Manoj