2014-03-19 76 views
0

我正在嘗試繪製一個圈內的數字,並且存在文本居中問題。以下是我使用以顯示的TextViewAndroid文本居中

<RelativeLayout 
    android:id="@+id/label" 
    android:layout_width="72dip" 
    android:layout_height="72dip" 
    android:layout_centerVertical="true" 
    android:layout_alignParentLeft="true" 
    android:layout_margin="8dip" > 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@drawable/hole_background" 
     android:layout_centerInParent="true"/> 
    <TextView 
     android:id="@+id/hole" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:textColor="@android:color/white" 
     android:textSize="56sp" 
     android:textStyle="bold" 
     android:gravity="center"/> 
</RelativeLayout> 

的問題是它僅僅是朝向底部稍微的XML(由我測試設備上的約10個像素)。這是從視圖層次觀衆的截圖,顯示什麼我談論...

enter image description here

我試圖合併的意見,並使用背景如here,或刪除字體填充類似建議here但既不工作,字體填補結束了,如下圖所示...

enter image description here

我目前正在使用負邊距來調整它來尋找正確的,但似乎並不像正確的方法來做到這一點。有沒有人有任何想法如何使文本居中,而不使用負邊距,我必須根據文本大小手動檢查?

在此先感謝

+2

這很可能是一個字體指標問題 - 居中不是基於實際字形,而是基於文本基線和垂直範圍。想象一下,如果你垂直居中「a」或「。」,會發生什麼。 - 顯然,它們不會位於中心,而是位於圓圈的中心線之下,因此大寫字符會顯示爲*更多*居中。我不知道除了嘗試使用不同的字體或手動修改之外,您還可以做其他任何事情。 – 323go

+1

這樣做很有意義,我並沒有真正考慮不同字符大小如何起作用。由於我有一個非常具體的用例,我只創建了一個自定義視圖,該視圖基於所繪文本的實際高度來處理居中。感謝您的意見 – StackJP

回答

1

因此,基於LairdPleng和323go的評論,我最終創建了一個自定義視圖。下面的視圖會做定心正是基於數量正在繪製的高度...

public class Label extends View { 

    private static final int TEXT_SIZE = 56; 

    private String mText; 

    private float mCenterX; 
    private float mCenterY; 
    private float mRadius; 

    private Paint mCirclePaint; 
    private Paint mTextPaint; 
    private Rect mTextBounds; 

    public HoleLabel(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     setupCanvasComponents(context); 
    } 

    public HoleLabel(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setupCanvasComponents(context); 
    } 

    public HoleLabel(Context context) { 
     super(context); 
     setupCanvasComponents(context); 
    } 

    public void setText(String text) { 
     if (!StringUtils.equals(mText, text)) { 
      mText = text; 
      invalidate(); 
     } 
    } 

    private void setupCanvasComponents(Context context) { 
     mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     mCirclePaint.setColor(Color.BLACK); 
     mCirclePaint.setStyle(Paint.Style.FILL); 

     Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/CustomFont.otf"); 
     DisplayMetrics displayMetrics = new DisplayMetrics(); 
     ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) 
       .getDefaultDisplay().getMetrics(displayMetrics); 
     float scaledDensity = displayMetrics.scaledDensity; 

     mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG); 
     mTextPaint.setColor(Color.WHITE); 
     mTextPaint.setStyle(Paint.Style.FILL); 
     mTextPaint.setTextSize(TEXT_SIZE * scaledDensity); 
     mTextPaint.setTypeface(font); 
     mTextPaint.setTextAlign(Align.CENTER); 

     mTextBounds = new Rect(); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 

     mCenterX = w/2.0f; 
     mCenterY = h/2.0f; 
     mRadius = w/2.0f; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     // Draw the background 
     canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint); 

     // Draw the text 
     if (mText != null) { 
      mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBounds); 
      canvas.drawText(mText, mCenterX, (mCenterY + mTextBounds.height()/2), mTextPaint); 
     } 
    } 

} 

以XML ...

<com.example.widget.Label 
     android:id="@+id/label" 
     android:layout_width="72dip" 
     android:layout_height="72dip" 
     android:layout_centerVertical="true" 
     android:layout_alignParentLeft="true" 
     android:layout_margin="8dip" /> 

結果是...

enter image description here

我有一個非常具體的用例,所以我不知道如果它能夠很好地工作,如果使用較不嚴格的尺寸規格,但它是我的方式。

0

會將此添加爲評論,但沒有足夠的信譽。根據323go的評論進行擴展,您可能會發現使用圖像處理數字更容易,而不是花費大量時間更改字體並手動調整偏移量 - 這可能在一個dpi上看起來不錯,然後在另一個dpi上再次查看。