Android文字中心

时间:2014-03-19 00:27:27

标签: android textview centering android-fonts

我试图在一个圆圈内绘制一个数字,并且在文本中心存在问题。以下是我用来显示TextView

的xml
<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>

问题是它稍微偏向底部(在我测试的设备上大约10个像素)。这是来自视图层次结构查看器的屏幕截图,显示了我正在谈论的内容......

enter image description here

我尝试过组合视图并使用here之类的背景,或者像建议的here一样删除字体填充但是没有效果,字体填充最终如下所示。 ..

enter image description here

我目前正在使用负边距来调整它以使其看起来正确,但这似乎不是正确的方法。有没有人对如何在不使用负边距的情况下使文本居中有任何想法,我必须根据文字大小手动检查?

提前致谢

2 个答案:

答案 0 :(得分: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

我有一个非常具体的用例,所以我不知道如果尺寸规格不那么严格它是否能很好用,但这是我的选择。

答案 1 :(得分:0)

将此添加为评论,但没有足够的声誉。扩展323go的评论,您可能会发现将图像用于数字更容易,而不是花费大量时间来更改字体和手动调整偏移 - 这可能在一个dpi上看起来很好,然后再在另一个上查看。