Mikooos
Mikooos

Reputation: 5430

Android and   in TextView

is it possible to add   in TextView? Has anyone achieved similar functionality?

I want to have non-breakable space in TextView.

Upvotes: 136

Views: 61774

Answers (9)

Рома Богдан
Рома Богдан

Reputation: 649

I needed narrow no-break space (nnbs) in my app (its smaller then regular space) but nothing worked for me.

So i made this extension to simulate nnbs

For spannable

fun SpannableString.transparent(symbol: String): SpannableString {
    val startIndex = indexOf(symbol)
    val endIndex = startIndex + symbol.length

    setSpan(ForegroundColorSpan(android.R.color.transparent), startIndex, endIndex, 0)
    return this
}

fun SpannableString.fontSize(symbol: String, fontSize: Int): SpannableString {
    val startIndex = indexOf(symbol)
    val endIndex = startIndex + symbol.length

    setSpan(AbsoluteSizeSpan(fontSize), startIndex, endIndex, SPAN_INCLUSIVE_INCLUSIVE)
    return this
}

For TextView:

/**
 * Font size divider for narrow no-break space
 */
const val NNBS_FONT_SIZE_DIVIDER = 3f

/**
 * Unique symbol for simulating narrow no-break space
 */
const val NNBS_SYMBOL = "$"

/**
 * For some reasons, Android not supporting narrow no-break space.
 * This extension make @param symbol transparent and decrease font size to
 * simulate narrow no-break space
 */
fun TextView.narrowNoBreakSpace(symbol: String, originalText: String) {
    val nnbsFontSize = (textSize / NNBS_FONT_SIZE_DIVIDER).roundToInt()

    text = SpannableString(originalText)
        .transparent(symbol)
        .fontSize(symbol, nnbsFontSize)
}

Usage:

val text = "Here is >$NNBS_SYMBOL< narrow no-break space."
textView.narrowNoBreakSpace(NNBS_SYMBOL, text)

Upvotes: 0

Demigod
Demigod

Reputation: 5635

Strange, but in my case non of these two worked:

  • &nbsp;
  • \u00A0 The TextView was showing them as text.

So I just inserted non-breaking space as it is: " "

Upvotes: 1

Dan Dyer
Dan Dyer

Reputation: 54495

TextView respects the Unicode no-break space character (\u00A0), which would be a simpler/lighter solution than HTML.

Upvotes: 225

Madhan Sekar
Madhan Sekar

Reputation: 31

This worked for me:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    textview.setText(Html.fromHtml(your string, Html.FROM_HTML_MODE_LEGACY));
} else {
    textview.setText(Html.fromHtml(your string);
}

Upvotes: 3

TWiStErRob
TWiStErRob

Reputation: 46480

It is possible to use &nbsp; to have a readable solution. Including \u00A0 or &#160; or &#xa0;/&#x00a0; in the text doesn't really convey much information to the reader of the source code (or translator for that matter), unless you remember the hex codes. Here's a way to use the named entity in strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
    <!ENTITY nbsp "&#160;"><!-- non-breaking space, U+00A0 -->
]>
<resources>
    ...
</resources>

This will create the missing declaration. The original HTML declaration can be found in https://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent referenced from the usual XHTML DTDs. All this works, because the XML parser reads these and substitutes while loading the file, so the entity won't be present in the resulting compiled resources.

&nbsp; in Android Text (CharSequence) Resources

<!-- Defined in <resources> -->
<string name="html_text">Don\'t break <b>this&nbsp;name</b></string>

<!-- Used in a layout -->
<TextView
    android:layout_width="130dp"
    android:layout_height="wrap_content"
    android:background="#10000000"
    android:text="@string/html_text"
    />

Device and preview (preview doesn't recognize HTML)
HTML on device HTML in preview

&nbsp; in Android String (formatted) Resources

<!-- Defined in <resources> -->
<string name="formatted_text">%1$s is&nbsp;nice</string>

<!-- Used in a layout -->
<TextView
    android:layout_width="130dp"
    android:layout_height="wrap_content"
    android:background="#10000000"
    tools:text="@string/formatted_text"
    />

Then in code:

String contents = getString(R.string.formatted_text, "Using an &nbsp;");
((TextView)view.findViewById(android.R.id.text1)).setText(contents);

Device and preview (preview doesn't recognize entities and Java strings are literal text!)
formatted on device formatted in preview

Further tricks

These are just example uses of DTD entities, use it base on your own preference.

<!ENTITY con "\&apos;"><!-- contraction, otherwise error: "Apostrophe not preceded by \"
                            Sadly &apos; cannot be overridden due to XML spec:
                            https://www.w3.org/TR/xml/#sec-predefined-ent -->
<!ENTITY param1 "&#37;1$s"><!-- format string argument #1 -->

<string name="original">Don\'t wrap %1$s</string>
<string name="with_entities">Don&con;t wrap &param1;</string>

Both of them help highlighting: highlighted XML entities

Upvotes: 39

Jon
Jon

Reputation: 9823

One unique situation I ran into was adding a non-breaking space to a string resource that took String.format parameters.

<resources>
    <string name="answer_progress" formatted="false">Answered %d of %d</string>
</resources>

I tried to simply copy and past the non-breaking space character into the string and it was replaced with a regular old space after compiling.

Removing the formatted="false", numbering the format args and using the backslash notation worked for me:

<resources>
    <string name="answer_progress">Answered %1$d\u00A0of\u00A0%2$d</string>
</resources>

Upvotes: 3

kameny
kameny

Reputation: 2370

This is an example that using nbsp in a TextView

<string name="text">Example:\u00A0</string>

Upvotes: 1

rds
rds

Reputation: 26994

The TextView should respect the non breaking space

<string name="test">Hello&#160;world</string>

or

new TextView("Hello\u00A0world");

Upvotes: 24

Brenagwynn
Brenagwynn

Reputation: 371

\u00A0 is a non-breaking space, \u0020 is not a non-breaking space

Upvotes: 27

Related Questions