斜体TextView使用wrap_contents参数时似乎会在右侧边缘裁剪文本

66
<TextView android:id="@+id/prodLbl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:textColor="#FFFFFF"
    android:textSize="30dip"
    android:textStyle="italic"
    android:text="Magnifico"
    />

在480x800模拟器或Nexus One上,最右边的字符似乎被裁剪了几个像素。

我认为这看起来像一个 bug,但我只是一个 Android 初学者。 我试着在左右两侧添加边距,但它仍然继续裁剪。 最后,我的解决方法是在文本的两侧添加一个空格。 还有其他解决方案吗?


你能发布一张你所看到的图片吗? - user432209
请查看右侧的'o'。 - Grego
你提到了边界,你是指内边距吗? - Andrew White
这个问题也困扰着我。 - Daniel
这在2023年仍然发生,真是疯狂。 ‍♂️ - mtrakal
14个回答

29

android:layout_width="wrap_content"会为你提供一个用于包裹内容呈现的矩形。对于普通文本(非斜体),这将完美地工作。

一旦启用了italic斜体文本,包装文本将尝试适应矩形,因此右侧的字符将被截断,除非它无法被截断(例如.)1等)。

建议的解决方案是在文本末尾加上一个空格(或者有更好的方法吗?)

PS:这同样适用于android:gravity="right",因为文本将被推向最右侧。如果我们有italic斜体文本,我们会面临同样的问题。


3
这太不可思议了...为什么,安卓先生?告诉我这是一个漏洞,会被修复的。 - Jack'
7
永远不会被修复。这个问题是从2010年开始的,而现在我在2022年仍在寻找解决方案... - jeff
如果您添加空格或任何其他字符,空格将根据TextView文本大小而增加。如果有人动态增加文本大小,则空格也会增加。 - Jayakrishnan

29

这在每种语言中都不起作用。 - doctorram

13

我在我的 strings.xml 文件中向所有字符串的末尾添加了 " \"。其中 \ 是转义字符,这样我可以解决问题,但这种解决方法并不好。希望这可以帮到你。


1
这是唯一可靠的解决方法。如果您使用资源字符串,尾随空格将被删除(为什么会这样?),因此没有效果,但斜杠可以解决这个问题。 - Reuben Scratton
我不认为这是XML的转义字符,至少我在这里没有看到:http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references但这对我来说绝对有效!我想知道为什么。 - nmr

8

只需在文本末尾添加一个额外的空格。在XML中,您必须在末尾添加\u0020,否则XML默认情况下会忽略开头/结尾的空格。


使用setTextSkewX(这是另一种使文本倾斜的方法)时,我遇到了同样的问题。这也解决了那个问题。 - thecoolmacdude

8

发现另一种解决方案(在使用wrap_content时测试了4.1.2和4.3)。如果你扩展TextViewEditText类,可以通过以下方式重写onMeasure方法:

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    final int measuredWidth = getMeasuredWidth();
    final float tenPercentOfMeasuredWidth = measuredWidth * 0.1f;
    final int newWidth = measuredWidth + (int) tenPercentOfMeasuredWidth;

    setMeasuredDimension(newWidth, getMeasuredHeight());
}

在2022年,这个回答仍然非常有效。谢谢分享。这会影响应用程序的性能吗? - RAINA

6

您可以在字符串中添加一个HAIR SPACE

<string name="hair_space">&#x200A;</string>

String hairSpace = getContext().getString(R.string.hair_space);
textView.setText(hairSpace + originalString + hairSpace)

1
这个很好用,谢谢!我讨厌这些谷歌强迫我们做的Hack! - Someone Somewhere

2
这同样适用于固定宽度的 TextView,而不仅仅是 "wrap_content"。我不确定这个问题是否与版本有关,因为一些评论者已经提到了。在所有 Honeycomb 版本中我都看到了这个问题。从我所见,设置边距、填充、使用固定宽度或自定义真斜体字体都不能解决这个问题。

现在可以通过在XML中设置true-italic字体来解决这个问题。感谢提示。请检查我的答案。 - sziraqui

2

通过查看源代码,我发现设置阴影会扩展剪辑矩形。

一个技巧是设置一个无形的阴影,就在字符的外面。

例如:

android:shadowRadius="2"
android:shadowDx="2"
android:shadowColor="#00000000"

我认为这个解决方案更好,因为它不会扩展TextView的宽度,而当添加一个额外字符时可能会发生这种情况(特别是在有背景的情况下更明显)。


Edited: Remove the dips - Che Jami

2

一种正确而干净的解决方案:

使用斜体自定义字体代替设置textStyle='italic' 例如:

<android.support.v7.widget.AppCompatTextView
            android:text="yolO"
            app:fontFamily="@font/roboto_italic"/>

我还没有在普通的TextView上尝试过,但是从我的观察来看,问题出在textStyle='italic'上。

不需要任何hack就可以解决问题!

以下是证明textStyle属性有问题的证据:

我创建了一个自定义的fontFamily,并为正常、粗体和斜体定义了typeface。

res/font/app_font_family.xml

<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font app:fontStyle="normal" app:fontWeight="400" app:font="@font/roboto_regular"/>
    <font app:fontStyle="italic" app:fontWeight="400" app:font="@font/roboto_italic" />
    <font app:fontStyle="normal" app:fontWeight="700" app:font="@font/roboto_medium"/>
</font-family>

现在当我使用这个字体族并应用textStyle='italic'时,最右边的字符仍然被裁剪了。
<android.support.v7.widget.AppCompatTextView
            android:text="yolO"
            app:fontFamily="@font/app_font_family"
            android:textStyle='italic' />

这是在Api 23上使用支持库28.0.0和Android Studio 3.2。


1
最佳解决方案 - WOLVERINE
对我来说不起作用,即使在我的资源中使用了Roboto-Italic字体,它仍然被截断。 - Michael P

1
这是我的解决方案:格式化TextView并测量它的宽度,然后将测量得到的宽度加上1像素设置为TextView的宽度。
TextView textView = new TextView(this);
textView.setText("Text blah blah");
textView.setTypeface(typeface, Typeface.BOLD_ITALIC)
textView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
textView.setLayoutParams(new LayoutParams(textView.getMeasuredWidth() + 1, 
                                             LayoutParams.WRAP_CONTENT));

为我工作。希望这些能帮到你。


这是一个适当的解决方案,而不是一个hack。 - sziraqui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接