2011-09-28 72 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