【问题标题】:Android Text CenteringAndroid 文本居中
【发布时间】:2014-03-19 00:27:26
【问题描述】:

我正在尝试在圆圈内绘制一个数字,但在文本居中时遇到问题。以下是我用来显示 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 像素)。这是视图层次结构查看器的屏幕截图,显示了我在说什么...

我尝试合并视图并使用背景,例如here,或者像建议的here 那样删除字体填充,但都没有奏效,字体填充如下所示...

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

提前致谢

【问题讨论】:

  • 这很可能是字体指标问题——居中不是基于实际字形,而是基于文本基线和垂直范围。想象一下,如果将“a”或“.”垂直居中会发生什么情况。 -- 显然,它们不会在中心,而是在圆的中心线下方,因此大写字符会出现更多居中。我不知道除了尝试不同的字体或手动更正之外,您真的可以做任何事情。
  • 这很有道理,我并没有真正考虑不同的字符大小将如何发挥作用。由于我有一个非常具体的用例,我刚刚创建了一个自定义视图,它根据正在绘制的文本的实际高度处理居中。感谢您的输入

标签: android textview centering android-fonts


【解决方案1】:

因此,基于 LairdPleng 和 323go 的 cmets,我最终只是创建了一个自定义视图。以下视图将完全根据正在绘制的数字的高度进行居中...

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" />

结果是……

我有一个非常具体的用例,所以我不知道如果使用不那么严格的尺寸规格是否能很好地工作,但这是适合我的方法。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-18
      • 2017-06-28
      • 2021-09-29
      • 2015-03-21
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      相关资源
      最近更新 更多