原始字符串:
Lorem ## ipsum ## dolar ## sit ## atem。 Lorem ipsum dolar坐## atem ##。
格式化后:
Lorem #ipsum dolar #sit atem。 Lorem ipsum dolar坐#atem。
但只有最后一个有我想要的Formating。见下图。
CODE
private void format() {
CharSequence text = editContent.getText();
MovementMethod movementMethod = editContent.getMovementMethod();
if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod))
{
editContent.setMovementMethod(LinkMovementMethod.getInstance());
}
text = setSpanBetweenTokens(text, "##", new ForegroundColorSpan(0xFF0099FF), new UnderlineSpan(), new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show();
}
});
editContent.setText(text);
}
private static CharSequence setSpanBetweenTokens(CharSequence text, String token, CharacterStyle... characterStyle) {
int tokenLen = token.length();
int start = text.toString().indexOf(token) + 1;
int end = text.toString().indexOf(token, start);
while (start > -1 && end > -1)
{
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
for (CharacterStyle c : characterStyle) {
spannableStringBuilder.setSpan(c, start, end, 0);
}
spannableStringBuilder.delete(end, end + tokenLen);
spannableStringBuilder.delete(start - 1, start);
text = spannableStringBuilder;
start = text.toString().indexOf(token) + 1;
end = text.toString().indexOf(token, start);
}
return text;
}
修改
我的最终解决方案
private void format() {
CharSequence text = editContent.getText();
MovementMethod movementMethod = editContent.getMovementMethod();
if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod))
{
editContent.setMovementMethod(LinkMovementMethod.getInstance());
}
text = setSpanBetweenTokens(text, "##");
editContent.setText(text);
}
private static CharSequence setSpanBetweenTokens(CharSequence text, String token) {
int tokenLen = token.length();
int start = text.toString().indexOf(token) + 1;
int end = text.toString().indexOf(token, start);
while (start > -1 && end > -1)
{
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
spannableStringBuilder.setSpan(new ForegroundColorSpan(0xFF0099FF), start, end, 0);
spannableStringBuilder.setSpan(new UnderlineSpan(), start, end, 0);
spannableStringBuilder.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Log.d("DEBUG", "Click");
}
}, start, end, 0);
spannableStringBuilder.delete(end, end + tokenLen);
spannableStringBuilder.delete(start - 1, start);
text = spannableStringBuilder;
start = text.toString().indexOf(token) + 1;
end = text.toString().indexOf(token, start);
}
return text;
}
答案 0 :(得分:4)
为每个跨度传递不同的对象:
spannableStringBuilder.setSpan(c, start, end, 0);
您为每个范围传递相同的对象:
new ForegroundColorSpan(0xFF0099FF)
当spannableStringBuilder中存在span对象时,它只更改边界,而不是添加新的span。
答案 1 :(得分:3)
我建议采用更简单的方法。如果你的格式需求是基本的,一个简单的正则表达式+ Html.fromHtml()应该可以做到这一点:
private void format() {
String mText = editContent.getText();
Spanned mSpannedText = Html.fromHtml(mText.replaceAll("##(.*?)##)","<font color=\"0xFF0099\">#$1</font>"),
editContent.setText(mSpannedText);
}
答案 2 :(得分:1)
最终解决方案正确循环,但是您使用
时,第一个令牌将无法正确删除int start = text.toString().indexOf(token) + 1;
仅当您的令牌长度为1个字符时才有效。由于您选择的令牌是##,因此更改上述代码以使用已创建的变量tokenLen
int start = text.toString().indexOf(token) + tokenLen;
这将确保正确编辑您的文本并删除所有令牌的痕迹。