Android:使用 Spannable 将带有项目符号的文本放入 TextView

Android: using Spannable for putting text with bullets into TextView

我需要用多种语言输入一些文本。 文本看起来像:

标题

另一个标题

项目符号与其他文本的颜色不同。

我在 Android 中听说过 Spannable,但不幸的是我只能将 spanfromend int 值一起使用。问题在于,在不同的语言中,我的话会有不同的位置,因此可跨越的文本不适合我。你能帮我用简单的方法解决这个问题吗?

我厌倦了处理带项目符号的文本,所以我写了一个 TextView 子类,我称之为 BulletTextView

我和你一样在资源文件中有文字。我将所有文本格式化为使用 Unicode 项目符号字符 \u2022 来标记项目符号。因此示例文本可能如下所示:

<string name="product_description_text">Our product is absolutely amazing, because 
    it has these features:
    \n\n\u2022 First awesome feature
    \n\u2022 Second awesome feature
    \n\u2022 Third awesome feature
    \n\n(Note that users with a free trial license can\'t access these features.)\n</string>

BulletTextView 覆盖 TextView.setText() 扫描文本中的项目符号字符,删除它们并保存位置以标记项目符号范围:

@Override
public void setText(CharSequence text, BufferType type) {

    StringBuilder sb = new StringBuilder();
    List<Integer> markers = new ArrayList<Integer>();

    for (int i = 0; i < text.length(); i++) {
        char ch = text.charAt(i);

        switch (ch) {

        case '\u2022':

            // we found a bullet, mark the start of bullet span but don't append the bullet char
            markers.add(sb.length());

            // ... I do some other stuff here to skip whitespace etc.
            break;

        case '\n':

            // we found a newline char, mark the end of the bullet span
            sb.append(ch);
            markers.add(sb.length());

            // ... I do some stuff here to weed out the newlines without matching bullets

            break;

        // ... I have some special treatment for some other characters,
        //     for instance, a tab \t means a newline within the span

        default:
            // any other character just add it to the string
            sb.append(ch);
            break;
        }
    }

    // ... at the end of the loop I have some code to check for an unclosed span

    //  create the spannable to put in the TextView
    SpannableString spannableString = new SpannableString(sb.toString());

    // go through the markers two at a time and set the spans
    for (int i = 0; i < markers.size(); i += 2) {
        int start = markers.get(i);
        int end = markers.get(i+1);
        spannableString.setSpan(new BulletSpan(gapWidth), start, end, Spannable.SPAN_PARAGRAPH);
    }

    super.setText(spannableString, BufferType.SPANNABLE);
}

我遗漏了一些特定于我的应用程序的代码,但这是解决您的问题的基本框架。

不确定要不要让子弹颜色不同,但有一个 BulletSpan 构造函数 public BulletSpan(int gapWidth, int color) 可以解决问题。

我试图弄清楚如何使用 LineHeight 制作更大的线条来分隔项目符号段落,但我无法让它工作。我只是用换行符来分隔两个项目符号部分。

原生 Android TextView 不支持 HTML ul/li 元素(项目符号列表)。因此,您将有两个(或更多)选项: