Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zero-width line breaking space for Android

Tags:

android

Does anyone know if \u200b should be working on Android as a zero width space that functions as a line break if the TextView length is exceeded by the text of the TextView? It appears that only \u0020 is line breaking for me, but I'm not able to figure out how to have a zero width version of it. \u200b is what I expect should work, per the following link, but it only does the zero-width space and doesn't break...and as stated, only \u0020 is line breaking.

http://www.cs.tut.fi/~jkorpela/chars/spaces.html

I've attached the view of an Activity I'm using for testing where U+ is being used in place of \u.

I've also tried using the fromHtml option to see if there is an Html option that works but haven't had any luck with arial.

Here's the test code I'm using

public class TextSpaceActivity extends Activity {

public static void start( Context ctx ) {
    ctx.startActivity(  new Intent( ctx, TextSpaceActivity.class )  );
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.text_space_activity );
    setTitle( "TextSpaceActivity" );

    setText( R.id.tsa_txvw_1, "abc\u0020123\u0020xyz\u0020987" );
    setText( R.id.tsa_txvw_2, "abc\u200a123\u200axyz\u200a987" );
    setText( R.id.tsa_txvw_3, "abc\u200b123\u200bxyz\u200b987" );
}

TextView txvw;
private void setText( int txvwResId, String txt ) {
    txvw = (TextView)findViewById( txvwResId );
    txvw.setText( txt );
}
}

enter image description here

like image 659
mmaitlen Avatar asked Nov 27 '12 23:11

mmaitlen


People also ask

How do you make a zero width space?

Alt + 8203 A zero-width space is, for the most part, invisible. It's a space that you can put into Word and other programs to divide up a long line of text without breaking it up visually.

How do you get rid of zero width space?

To remove zero-width space characters from a JavaScript string, we can use the JavaScript string replace method that matches all zero-width characters and replace them with empty strings. Zero-width characters in Unicode includes: U+200B zero width space. U+200C zero-width non-joiner Unicode code point.

What is the purpose of zero width space?

The zero-width space (​), abbreviated ZWSP, is a non-printing character used in computerized typesetting to indicate word boundaries to text-processing systems in scripts that do not use explicit spacing, or after characters (such as the slash) that are not followed by a visible space but after which there may ...

How do you use zero width space in HTML?

The code &#8203 is the HTML code for the zero width space. From ptiglobal: The zero-width space can be used to enable line wrapping in long words, when using languages that don't use spaces to separate words.


2 Answers

I don't believe the line-breaking algorithm understands the zero-width line-break, or soft hyphens, or the line- or paragraph-separator characters for that matter. Here's the code from the Android source that decides if there can be a line break here (android.text.StaticLayout, lines 358-366 in the source):

// From the Unicode Line Breaking Algorithm (at least approximately)
boolean isLineBreak = isSpaceOrTab ||
        // / is class SY and - is class HY, except when followed by a digit
        ((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
        (j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
        // Ideographs are class ID: breakpoints when adjacent, except for NS
        // (non-starters), which can be broken after but not before
        (c >= CHAR_FIRST_CJK && isIdeographic(c, true) &&
        j + 1 < spanEnd && isIdeographic(chs[j + 1 - paraStart], false));

where isSpaceOrTab is defined just above (line 343) as:

boolean isSpaceOrTab = c == CHAR_SPACE || c == CHAR_TAB;

All the CHAR_ constants are plain character constants, so there's nothing like isspace going on. Lines 952-958 in the same file:

private static final char CHAR_FIRST_CJK = '\u2E80';

private static final char CHAR_NEW_LINE = '\n';
private static final char CHAR_TAB = '\t';
private static final char CHAR_SPACE = ' ';
private static final char CHAR_SLASH = '/';
private static final char CHAR_HYPHEN = '-';

Looking at your other comments, I see you're trying to break Chinese correctly. You might not have to do anything special: as the isIdeographic call above hints, it tries to break between two ideographs without inserting spaces. Only the StaticLayout breaker does this: DynamicLayout only uses newline characters, so it will only break correctly on static text.

I'm afraid from my research it looks like you're screwed. My only suggestion for a work-around would be to use a WebView instead of a TextView, and use the superior line-breaking capabilities of the system's web browser instead of the limited implementation TextView offers.

like image 68
Dan Hulme Avatar answered Sep 29 '22 13:09

Dan Hulme


Since Lollipop, \u200b is supported.

This is implemented in StaticLayout with a native call on nLineBreakOpportunities.

like image 45
rds Avatar answered Sep 29 '22 11:09

rds