垂直居中文本与视图高度无关?
Posted
技术标签:
【中文标题】垂直居中文本与视图高度无关?【英文标题】:Center text vertically independently of View height? 【发布时间】:2015-03-31 21:42:49 【问题描述】:我正在尽力使文本垂直居中,但我无法做到。问题是我有一排带有 height=fill_parent 和 weight=1 的按钮,随着行变小,我的文本开始触及视图的底部,如下所示:
我尝试删除填充、边距、更改高度等。但似乎没有任何作用。
即使文本大小接近视图高度,如何垂直对齐?
这是包含数字 5 的视图的代码:
<Button
android:layout_
android:layout_
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" />
【问题讨论】:
你在用什么ViewGroup
?我认为您的解决方案是 Gravity.CENTER
到 match_parent
孩子
你有什么理由使用android:textSize="90dp"
??尝试批准的指令并查看android:textSize="90sp"
嗨@Eltz,该应用程序适用于视力低下的人,并且已经使用了可能的最大文本大小。因此,如果我使用 SP,我可能会冒用户选择大文本大小并破坏 UI 的风险。所有按钮都在 TableRow 中,我尝试在按钮上将高度更改为 match_parent,但我仍然遇到同样的问题。我仍然认为这与身高无关。
我认为这是因为 Textview 的默认填充文本 ***.com/questions/4768738/… 。我尝试了他们的解决方案,但对我不起作用。
请为周围的视图或布局发布 XML。
【参考方案1】:
根据我的建议,如果您有两种选择来进行这样的布局并摆脱您遇到的问题。
1.使用 GridView
使用gridview,您将在所有四个方向(左、右、上、下)上拥有相等的空间。您不必担心网格项目的等间距。
<GridView
android:id="@+id/album_list"
android:layout_
android:layout_
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_
android:layout_ 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_ android:layout_
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 的输出。
如果此问题已解决,请告诉我。如果没有,我很乐意再次为您提供帮助。
享受编码... :)
【讨论】:
【参考方案2】:如果此按钮位于垂直方向的线性布局内。由于您定义了权重,因此您希望将高度设置为“0dp”而不是“fill_parent”。 使文本中心垂直。你试过 android:gravity:"center_vertical" 吗?
【讨论】:
【参考方案3】:试试这个
<LinearLayout
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_below="@+id/dialer_title"
android:orientation="vertical"
>
<LinearLayout
android:layout_
android:layout_
android:layout_weight="0.2" >
<ImageButton
android:id="@+id/btn1"
style="@style/DialPadButton"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_weight="0.2" >
<ImageButton
android:id="@+id/btn4"
style="@style/DialPadButton"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_weight="0.2" >
<ImageButton
android:id="@+id/btn7"
style="@style/DialPadButton"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_weight="0.2" >
<ImageButton
android:id="@+id/btnStar"
style="@style/DialPadButton"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_weight="0.2" >
<ImageButton
android:id="@+id/btnContacts"
style="@style/DialPadButton"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_weight="0.33"
android:contentDescription="@string/desc_backspace"
android:scaleType="centerCrop"
android:soundEffectsEnabled="true"
android:src="@drawable/dial_num_delete" />
</LinearLayout>
</LinearLayout>
这将创建具有相同按钮大小的电话经销商。 对于 style="@style/DialPadButton" 创建名称为 DialPadButton 的样式并根据需要自定义按钮。就我而言,我添加了值为 5dp 的 item name="android:layout_margin"。
【讨论】:
【参考方案4】:使用网格视图进行设计,您将拥有更多功能。否则在里面取一个线性布局,设置另外三个线性布局方向水平和权重总和= 3,将每个按钮放在子布局上,并为每个按钮赋予布局权重=1。
【讨论】:
将布局重心设置为按钮的中心【参考方案5】:这并不意味着文本“5”没有居中。文本“5”出现在略低于中心的位置,因为按钮没有足够的空间来布局其文本内容。即使提供了足够的高度,文本“5”仍将显示在略高于中心的位置。这是因为,有字符('y','g'等)的下降大于“5”(在布局文本时考虑最大可能的上升和下降,即使你的文本不包含更高的字形或非零字形下降)。另见this。
如果为行中的按钮提供更多高度,它们将整齐地居中对齐其文本。
【讨论】:
【参考方案6】:我建议使用TextView
而不是Button
,因为这样可以减少棘手的边距,并且可以让您更好地控制如何放置文本。 (一般我很少使用按钮,但倾向于让其他视图 TextView、ImageView、...改为可点击)
<TextView
android:layout_
android:layout_
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。
【讨论】:
【参考方案7】:我认为最简单的方法是使用 AutoFitTextView
您可以从此链接获取此库:https://github.com/grantland/android-autofittextview
它将根据当前高度和宽度动态调整文本大小。
希望对你有所帮助。
祝你好运。
【讨论】:
【参考方案8】:尝试使用负的顶部填充,例如:
<Button
android:layout_
android:layout_
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
为不同的屏幕密度使用不同的值。
【讨论】:
【参考方案9】:你不能使用上间距来居中,因为它属于字体。我的意思是每种字体都有上升和下降指标。见下图。
所以当 android 居中文本时,它会计算它的整体高度(包括上和下间距)。并且比中心结果正确。您可以获取 FontMetrics 以查看字体 acsent 和下降值。
例如。调用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
有趣吗?那么如何去除顶部和底部的间距并使用这个空间来居中字体呢?我看到了两种解决方案:
创建不包括这些间距的自定义组件和布局文本。如果 你只需要单行文本会很容易。请参阅 TextView 代码。
我们知道间距,所以我们可以相应地移动文本。将翻译设置为
一个按钮内容。要删除顶部间距,您可以执行以下操作:button.setTranslationY(fm.top - fm.ascent);
如果您希望文本居中
没有空格,请执行以下操作:button.setTranslationY((fm.top - fm.ascent) + (fm.bottom - fm.descent));
【讨论】:
以上是关于垂直居中文本与视图高度无关?的主要内容,如果未能解决你的问题,请参考以下文章