【问题标题】:Zero-width line breaking space for AndroidAndroid 的零宽度换行空间
【发布时间】:2016-02-10 05:17:42
【问题描述】:

有谁知道 \u200b 是否应该在 Android 上作为零宽度空间工作,如果 TextView 的文本超过 TextView 的长度,则该空间用作换行符?似乎只有 \u0020 对我来说是换行符,但我无法弄清楚如何拥有它的零宽度版本。 \u200b 是我期望的工作,根据以下链接,但它只做零宽度空间并且不会中断......并且如前所述,只有 \u0020 是换行符。

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

我附上了我用来测试 U+ 代替 \u 的 Activity 的视图。

我也尝试使用 fromHtml 选项来查看是否有一个 Html 选项有效,但没有任何运气使用 arial。

这是我正在使用的测试代码

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

【问题讨论】:

  • 你能用这个 System.getProperty("line.separator")
  • 你用 ​ 尝试过 HTML统一码?
  • 四年后,我也遇到了同样的问题。我的安卓版本是 6.0.1。任何人都可以验证 Android 仍然不支持这个吗?

标签: android


【解决方案1】:

我不相信换行算法理解零宽度换行符、软连字符或行或段落分隔符字符。这是来自 Android 源代码的代码,它决定此处是否可以换行(android.text.StaticLayout,源代码中的第 358-366 行):

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

isSpaceOrTab 在上面(第 343 行)定义为:

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

所有CHAR_ 常量都是纯字符常量,所以没有像isspace 这样的东西。同一文件中的第 952-958 行:

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 = '-';

看看你的其他cmets,我看到你正试图正确地破解中文。您可能不需要做任何特别的事情:正如上面的 isIdeographic 调用所暗示的那样,它会尝试在两个表意文字之间中断而不插入空格。只有StaticLayout 断路器会这样做:DynamicLayout 只使用换行符,因此它只会在静态文本上正确中断。

恐怕根据我的研究,您看起来像是被搞砸了。我对解决方法的唯一建议是使用 WebView 而不是 TextView,并使用系统 Web 浏览器的卓越换行功能而不是有限的实现 TextView 提供。

【讨论】:

  • 感谢您的帮助和研究...将不得不四处看看是否存在其他解决方案,但 WebView 可能是唯一的选择。可能应该使用特定的文本示例来查看它们的行为方式并从中做出决定。
【解决方案2】:

由于 Lollipop,支持\u200b

这是在 StaticLayout 中实现的,并在 nLineBreakOpportunities 上进行本机调用。

【讨论】:

  • 在哪里可以找到那个 nComputeLineBreaks 的来源?
  • 我也在使用 5.1 并在文本中添加 \u200b,在这种情况下,在警报中,不会自动将其视为中断空间。或许还需要一些进一步的设置?
  • 字体是否需要支持?
  • 啊,鉴于该代码,似乎不需要字体的支持。
【解决方案3】:

相关:我刚刚测试了使用零宽度空格字符实体 &amp;#8203; 作为应用程序标题的一部分,当应用程序的图标在桌面上呈现时,它按预期处理 Android 操作系统。

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

我在 Android 5.0 上试过这个;不过,不知道它是否可以在旧版本中使用。

【讨论】:

    【解决方案4】:

    在您的 strings.xml 中:

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

    在您的活动中:

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

    希望对你有帮助!

    【讨论】:

    • 这会强制换行,它不仅会在行太长时换行。
    【解决方案5】:

    如果您只想在浏览器中控制显示,您可以尝试在 CSS 中使用零宽度内联类:

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

    然后,在 HTML 中:

    abc<span class="zw"> </span>123
    

    【讨论】:

    • 问题是关于 Android 活动,而不是网页。
    猜你喜欢
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    相关资源
    最近更新 更多