适用于Android的零宽度打破空间

时间:2012-11-27 23:17:25

标签: android

如果TextView的文本超出TextView长度,是否有人知道\ u200b是否应该在Android上作为零宽度空间用作换行符?似乎只有\ u0020对我来说是破线,但我无法弄清楚如何获得它的零宽度版本。 \ u200b是我期望应该工作的,按照以下链接,但它只做零宽度空间并且不会破坏......并且如上所述,只有\ u0020是断线。

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

我附上了我正在使用的一个Activity的视图,用于测试U +代替\ u的位置。

我也尝试过使用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 );
}
}

enter image description here

5 个答案:

答案 0 :(得分:14)

我不相信断行算法能够理解零宽度换行符或软连字符,或者用于此问题的行或段落分隔符。以下是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 = '-';

看看你的其他评论,我看到你正试图正确打破中文。您可能不需要做任何特殊的事情:正如上面提到的isIdeographic调用,它试图在两个表意文字之间断开而不插入空格。只有StaticLayout断路器执行此操作:DynamicLayout仅使用换行符,因此它只会在静态文本上正确断开。

我害怕从我的研究中看起来你被搞砸了。我对解决方法的唯一建议是使用WebView而不是TextView,并使用系统网络浏览器的高级断行功能,而不是有限的实现TextView提供。

答案 1 :(得分:4)

自Lollipop以来,\u200b受到支持。

这是StaticLayoutnLineBreakOpportunities进行原生呼叫时实施的。

答案 2 :(得分:0)

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

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

我在Android 5.0上试过这个;但不知道它是否适用于旧版本。

答案 3 :(得分:-2)

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

希望它有所帮助!

答案 4 :(得分:-2)

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

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

然后,在HTML中:

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