Android:使用 Spannable 将带有项目符号的文本放入 TextView
Android: using Spannable for putting text with bullets into TextView
我需要用多种语言输入一些文本。
文本看起来像:
标题
- 一个
- 两个
- 三个
另一个标题
- 一个
- 两个
- 三个
项目符号与其他文本的颜色不同。
我在 Android
中听说过 Spannable
,但不幸的是我只能将 span
与 from
和 end
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
元素(项目符号列表)。因此,您将有两个(或更多)选项:
- 将 workarounds 与本机
TextView
结合使用。
使用第 3 方库。例如 html-textview 符合您的要求。
我需要用多种语言输入一些文本。 文本看起来像:
标题
- 一个
- 两个
- 三个
另一个标题
- 一个
- 两个
- 三个
项目符号与其他文本的颜色不同。
我在 Android
中听说过 Spannable
,但不幸的是我只能将 span
与 from
和 end
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
元素(项目符号列表)。因此,您将有两个(或更多)选项:
- 将 workarounds 与本机
TextView
结合使用。 使用第 3 方库。例如 html-textview 符合您的要求。