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

标签 android textview spannablestring

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

标题

  • 一个
  • 两个
  • 三个

另一个标题

  • 一个
  • 两个
  • 三个

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

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

最佳答案

我厌倦了处理带项目符号的文本,所以我写了一个 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:使用 Spannable 将带有项目符号的文本放入 TextView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33505802/

相关文章:

android - 如何部署特定于旧版 Android 版本的 apk

java - 自定义 View 未在 Activity 中显示

android - TextView 填充点

android - Textview 中的 2 列对齐

java - 如何从 TextView 中获取文本并将其格式化为美元货币?

android - 可扩展字符串错误

java - 如何将 Spannable 设置为 TextView?

android - broadcastreceiver onReceive问题 ACTION_MEDIA_BUTTON Android

Android:在绘制之前获取 View 的高度

android - 如何在 Android 中将一种 Spanned 类型更改为另一种 Spanned 类型?