垂直居中文本独立于视图高度?

Center text vertically independently of View height?

我正在尽力使文本垂直居中,但我做不到。问题是我有几行高度=fill_parent 和重量=1 的按钮,随着行变小,我的文本开始触及视图底部,如下所示:

我尝试删除填充、边距、更改高度等。但似乎什么也做不了。

即使文本大小接近视图高度,如何垂直对齐它?

这是包含数字 5 的视图的代码:

    <Button
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="5"
        android:layout_weight="1"
        tools:ignore="HardcodedText"
        android:clickable="false"
        android:textSize="90dp"
        android:textColor="?attr/color1"
        android:gravity="center"
        android:paddingLeft="@dimen/normal_margin"
        android:paddingRight="@dimen/normal_margin"
        android:padding="0dp" />

使用网格视图进行设计,您将拥有更多功能。否则在里面取一个线性布局,设置另外三个线性布局方向水平和权重总和= 3,将每个按钮放在子布局上并为每个按钮赋予布局权重=1。

并不是说文字“5”没有居中。文本“5”出现在略低于中心的位置,因为没有为按钮提供足够的 space 来布局其文本内容。即使提供了足够的高度,文本“5”仍会略高于中心。这是因为,有些字符('y'、'g' 等)的下降比“5”大(在布局文本时会考虑最大可能的上升和下降,即使您的文本不包含更高的字形或具有非零血统的字形)。另见 this.

如果为行中的按钮提供更高的高度,它们将整齐地居中对齐其文本。

如果此按钮位于垂直方向的线性布局内。由于您定义了权重,因此您希望将高度设置为“0dp”而不是 "fill_parent"。 使文本居中垂直。你试过了吗android:gravity:"center_vertical"?

我建议使用 TextView 而不是 Button,因为这样的边距不那么棘手,并且可以让您更好地控制如何放置文本。 (一般我很少使用按钮,但倾向于让其他视图TextView,ImageView,...改为可点击)

 <TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="5"
    android:layout_weight="1"
    tools:ignore="HardcodedText"
    android:clickable="false"
    android:textSize="90dp"
    android:textColor="?attr/color1"
    android:gravity="center"
    android:paddingLeft="@dimen/normal_margin"
    android:paddingRight="@dimen/normal_margin"
    android:padding="0dp" />

如果您需要某种关于 TextView 是否被按下的指示,您可以添加一个选择器作为背景。 为此,请查看 here.

最后,如果您希望文本适合任何可能的视图大小,请查看 AutoFitTextView

不能使用上间距居中,因为它属于字体。我的意思是每种字体都有上升和下降指标。见下图。

所以当 android 文本居中时,它会计算它的整体高度(包括上下间距)。并且中心结果是正确的。您可以获取 FontMetrics 以查看字体重音和下降值。 例如。调用 Paint.FontMetrics fm = textView.getPaint().getFontMetrics();我们得到:

fm = {android.graphics.Paint$FontMetrics@3668}
ascent = -25.976562
bottom = 7.5878906
descent = 6.8359375
leading = 0.0
top = -29.572266

有趣吗?那么如何去除顶部和底部间距并使用这个 space 来居中字体呢?我看到两个解决方案:

  • 创建不包括这些间距的自定义组件和布局文本。如果 您只需要单行文本,这很容易。请参阅 TextView 代码。

  • 我们知道间距,所以我们可以相应地移动文本。将翻译设置为 一个按钮内容。要删除顶部间距,您可以执行以下操作:
    button.setTranslationY(fm.top - fm.ascent); 如果你想让文字居中 没有间距,执行以下操作:button.setTranslationY((fm.top - fm.ascent) + (fm.bottom - fm.descent));

我认为最简单的方法是使用 AutoFitTextView

你可以从这个 link 得到这个库:https://github.com/grantland/android-autofittextview

它将根据当前的高度和宽度动态调整文本大小。

希望对您有所帮助。

祝你好运。

根据我的建议,如果您有两种选择来进行此类布局并摆脱您遇到的问题。

1.使用 GridView

使用 gridview,您将在所有四个方向(左、右、上、下)上获得相等的 space。您不必担心网格项的间距相等。

 <GridView
    android:id="@+id/album_list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:cacheColorHint="#00000000"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="spacingWidthUniform"
    android:drawSelectorOnTop="true"/>

只需尝试上面的代码,您将在网格中平均分布所有视图。

2。使用 TableLayout 和 TableRow

请检查以下代码以使用 TableLayout 和 TableRow 及其属性使所有视图均等排列。即使您减小 TableLayout 的高度和宽度,它在该视图中仍将保持均匀排列。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"                      android:layout_width="match_parent"
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:layout_margin="5dp">
<TableRow android:weightSum="3"
    android:layout_weight="1" android:gravity="center">
    <Button android:gravity="center"
        android:textSize="13sp" android:textColor="#000000"
        android:text="1" android:layout_weight="1"/>
    <Button  android:gravity="center"
        android:textSize="13sp" android:textColor="#000000"
        android:text="1" android:layout_weight="1"/>
    <Button android:gravity="center"
        android:textSize="13sp" android:textColor="#000000"
        android:text="1" android:layout_weight="1"/>
</TableRow>

    <TableRow android:weightSum="3" android:layout_weight="1" android:gravity="center">
        <Button android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
        <Button  android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
        <Button android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
    </TableRow>

    <TableRow android:weightSum="3" android:layout_weight="1" android:gravity="center">
        <Button android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
        <Button  android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
        <Button android:gravity="center"
            android:textSize="13sp" android:textColor="#000000"
            android:text="1" android:layout_weight="1"/>
    </TableRow>
</TableLayout>

请查找此 TableLayout 的输出。

如果此问题已解决,请告诉我。如果没有,我很乐意再次为您提供帮助。

享受编码...:)

试试这个

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/dialer_title"

    android:orientation="vertical"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2" >

        <ImageButton
            android:id="@+id/btn1"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_1"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_1_no_vm" />

        <ImageButton
            android:id="@+id/btn2"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_2"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_2" />

        <ImageButton
            android:id="@+id/btn3"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_3"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_3" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2" >

        <ImageButton
            android:id="@+id/btn4"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_4"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_4" />

        <ImageButton
            android:id="@+id/btn5"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_5"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_5" />

        <ImageButton
            android:id="@+id/btn6"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_6"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_6" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2" >

        <ImageButton
            android:id="@+id/btn7"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_7"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_7" />

        <ImageButton
            android:id="@+id/btn8"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_8"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_8" />

        <ImageButton
            android:id="@+id/btn9"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_9"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_9" />
    </LinearLayout>

    <LinearLayout
        style="@style/DialPadRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2" >

        <ImageButton
            android:id="@+id/btnStar"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_astr"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_star" />

        <ImageButton
            android:id="@+id/btn0"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_0"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_0" />

        <ImageButton
            android:id="@+id/btnHash"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_hash"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="false"
            android:src="@drawable/dial_num_hash" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2" >

        <ImageButton
            android:id="@+id/btnContacts"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/string_menu_contacts"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="true"
            android:src="@drawable/selector_dial_contact_b" />

        <ImageButton
            android:id="@+id/btnCall"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/string_menu_call"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="true"
            android:src="@drawable/dial_num_call" />

        <ImageButton
            android:id="@+id/btnDelete"
            style="@style/DialPadButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.33"
            android:contentDescription="@string/desc_backspace"
            android:scaleType="centerCrop"
            android:soundEffectsEnabled="true"
            android:src="@drawable/dial_num_delete" />
    </LinearLayout>
</LinearLayout>

这将创建 phone 个具有相同按钮大小的经销商。 对于 style="@style/DialPadButton" 创建名称为 DialPadButton 的样式并根据需要自定义按钮。在我的例子中,我添加了值为 5dp 的项目名称="android:layout_margin"。

尝试使用负的顶部填充,例如:

<Button
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="5"
    android:layout_weight="1"
    tools:ignore="HardcodedText"
    android:clickable="false"
    android:textSize="90dp"
    android:textColor="?attr/color1"
    android:gravity="center"
    android:paddingLeft="@dimen/normal_margin"
    android:paddingRight="@dimen/normal_margin"
    android:paddingTop="-2dp" />

您可以尝试一下,并获得顶部填充的必要值。当然,您可以使用 @dimen.

为不同的屏幕密度使用不同的值