Italic TextView with wrap_contents seems to clip the text at right edge

AndroidTextviewItalic

Android Problem Overview


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

Seems to clip few pixels from the rightmost character, at least on 480x800 emulator or Nexus One.

To me it looks like a bug, but I'm just an Android beginner. I tried to add margins to left and right, but it still kept on clipping. In the end my hack around it was to add a single space on both sides of the text. Any other solutions?

Android Solutions


Solution 1 - Android

android:layout_width="wrap_content" , gives you a rectangle for wrapped content rendering. All will work well for normal text (non-italic).

Once you have italic text enabled, the wrapped text will try to fit into the rectangle and hence the rightmost character will be cut off unless its un-cut-able (such as ., ), 1, etc.)

Solution as suggested is to have a space at the end of the text (or anything better ??)

PS: This applies to android:gravity="right" too because the text will be pushed to the rightmost. If we have italic text, we face the same problem.

Solution 2 - Android

You could also use the Unicode no-break space character (\u00A0).

Solution 3 - Android

I added " \" to end of all strings in my strings.xml. \ is the escape character, so this way I could come over the issue, but this solution is nasty. Hope this helps.

Solution 4 - Android

Just add an extra space to the end of the text. In XML, you will have to add \u0020 to the end as otherwise XML ignores whitespace at the beginning/end by default.

Solution 5 - Android

Found another solution (tested on 4.1.2 and 4.3 while using wrap_content). If you extend TextView or EditText class you can override onMeasure method this way:

@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());
}

Solution 6 - Android

You can add a HAIR SPACE to your string

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

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

Solution 7 - Android

A proper and clean solution:

Use an italic custom font instead of setting textStyle='italic' For example:

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

I haven't tried it on regular TextView but from my observations, the problem is with textStyle='italic'.

Works without any hack!

Here's a proof of blaming textStyle attribute:

I made a custom fontFamily and defined typeface for normal, bold and italic

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>

Now when I use this fontFamily and apply textStyle='italic', the rightmost character is still clipped.

<android.support.v7.widget.AppCompatTextView
            android:text="yolO"
            app:fontFamily="@font/app_font_family"
            android:textStyle='italic' />

This is on Api 23 with support library 28.0.0 and Android Studio 3.2

Solution 8 - Android

This applies to fixed-width TextViews also, not just "wrap_content". I'm not sure if the issue is version-specific as some commenters have alluded to. I see the issue on all Honeycomb versions. From what I've seen the issue does not go away by setting margin, padding, using a fixed-width, or a true-italic custom typeface.

Solution 9 - Android

Looking at the source I found out that setting a shadow extends the clip rectangle.

A trick is to set an invisible shadow just beyond the character.

For example:

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

I think this solution is better as it will not extend the width of the TextView which may happen when adding an extra character (which is more apparent with a background).

Solution 10 - Android

This is my solution: Format textview and measure. After that set width of textview with 1 pixel add to the width measured.

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));

Working for me. Hope these help.

Solution 11 - Android

I also had the same issue and used a non-breaking space entity via HTML:

textView.setText("Magnifico" + Html.fromHtml("&nbsp;");

Solution 12 - Android

It seems to me that if you apply italic programatically, it does content wrapping correctly. So set the typeface of the TextView manually, e.g. in kotlin:

textView.typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)

Solution 13 - Android

Although I'd generally prefer sziraqui's answer that suggests using a true italic font, these are not always available.
As the problem at hand is caused by the mismeasurement of the text's boundaries, I just set android:layout_width="0dp", giving the TextView as much horizontal space as it needs. This might also not be ideal in all circumstances, but it's a simple and not too hackish solution for many situations.

Solution 14 - Android

Add a 3dp padding to the right on your TextView. I tried with 1dp and 2dp, but 3dp seemed to do the trick fully.

android:paddingRight="3dp"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGregoView Question on Stackoverflow
Solution 1 - AndroiddanfelabsView Answer on Stackoverflow
Solution 2 - AndroidSamView Answer on Stackoverflow
Solution 3 - AndroidXteraView Answer on Stackoverflow
Solution 4 - AndroidOleg VaskevichView Answer on Stackoverflow
Solution 5 - Androidkamil zychView Answer on Stackoverflow
Solution 6 - AndroidFrank NguyenView Answer on Stackoverflow
Solution 7 - AndroidsziraquiView Answer on Stackoverflow
Solution 8 - AndroidTenaciousView Answer on Stackoverflow
Solution 9 - AndroidChe JamiView Answer on Stackoverflow
Solution 10 - AndroidleeView Answer on Stackoverflow
Solution 11 - AndroidOushView Answer on Stackoverflow
Solution 12 - AndroidkalnarView Answer on Stackoverflow
Solution 13 - AndroidRautermannView Answer on Stackoverflow
Solution 14 - Androiduser750023View Answer on Stackoverflow