Zero-width line breaking space for Android

后端 未结 5 1294
庸人自扰
庸人自扰 2020-12-14 18:36

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?

相关标签:
5条回答
  • 2020-12-14 18:50

    In your strings.xml:

    <string name="sample_string"><![CDATA[abc123<br />xyz987]]></string>
    

    In your Activity:

    TextView textView = (TextView) findViewById(R.id.myText);
    textView.setText(Html.fromHtml(getResources().getString(R.string.sample_string)));
    

    Hope it helps!

    0 讨论(0)
  • 2020-12-14 18:53

    If you only want to control the presentation in a browser, you might try a zero-width inline class in CSS:

    .zw { display: inline-block; width: 0; }
    

    Then, in the HTML:

    abc<span class="zw"> </span>123
    
    0 讨论(0)
  • 2020-12-14 18:58

    Related: I just tested use of the zero-width space character entity &#8203; as part of an app title, and it is handled as expected when the app's icon is rendered on the desktop by the Android OS.

        <string name="app_name">
            App&#8203;Name&#8203;With&#8203;Many&#8203;Words
        </string>
    

    I tried this on Android 5.0; unknown whether it will work in older versions, however.

    0 讨论(0)
  • 2020-12-14 19:12

    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.

    0 讨论(0)
  • 2020-12-14 19:12

    Since Lollipop, \u200b is supported.

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

    0 讨论(0)
提交回复
热议问题