英文:
Use spannable in a loop for a mutable text
问题
这是您的翻译内容:
所以我的应用程序应该将用户的输入与应用程序提供的随机引用进行比较,我希望将正确的单词着色为绿色,错误的单词着色为红色。
问题在于我不知道如何在循环中使用Spannable
来实现这一点,特别是文本始终在变化。
这是代码:
if(quoteWords.length == resultWords.length){
for(int i = 0; i < quoteWords.length; i++) {
if (quoteWords[i].equals(resultWords[i])) {
// 将单词着色为绿色
} else {
// 将单词着色为红色
}
}
}
以下是我尝试过的内容:
if(quoteWords.length == resultWords.length){
SpannableStringBuilder fullStyledSentence = new SpannableStringBuilder();
ForegroundColorSpan correctColor = new ForegroundColorSpan(Color.GREEN);
ForegroundColorSpan wrongColor = new ForegroundColorSpan(Color.RED);
int start;
for(int i = 0; i < quoteWords.length; i++) {
start = fullStyledSentence.length(); // 获取当前 SpannableString 的长度
fullStyledSentence.append(quoteWords[i]);
if (quoteWords[i].equals(resultWords[i])) { // 使用单词长度对每个单词着色
fullStyledSentence.setSpan(correctColor, start, start + quoteWords[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.i("AzureSpeechRecognition", "第 " + i + " 个单词正确");
} else {
fullStyledSentence.setSpan(wrongColor, start, start + quoteWords[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.i("AzureSpeechRecognition", "第 " + i + " 个单词错误");
}
mQuoteBodyTextView.setText(null); // 清空重复添加的文本
mQuoteBodyTextView.append(fullStyledSentence + " ");
}
}
但是生成的文本没有着色,并且它们粘在一起没有空格。
英文:
So my app should compare the user's input with a random quote provided by the app, and I want to color the correct word with green and the wrong one with red.
the problem is that I don't know how to do it with Spannable
in a loop, and especially that the text is always changing.
This is the code:
if(quoteWords.length == resultWords.length){
for(int i = 0; i < quoteWords.length; i++) {
if (quoteWords[i].equals(resultWords[i])) {
//color the word with green
} else {
//color the word with red
}
}
}
And this is what I tried:
if(quoteWords.length == resultWords.length){
SpannableStringBuilder fullStyledSentence = new SpannableStringBuilder();
ForegroundColorSpan correctColor = new ForegroundColorSpan(Color.GREEN);
ForegroundColorSpan wrongColor = new ForegroundColorSpan(Color.RED);
int start;
for(int i = 0; i < quoteWords.length; i++) {
start = fullStyledSentence.length(); //get length of current SpannableString
fullStyledSentence.append(quoteWords[i]);
if (quoteWords[i].equals(resultWords[i])) { //color each word using its length
fullStyledSentence.setSpan(correctColor, start, start + quoteWords[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.i("AzureSpeechRecognition", "word number " + i + "is correct");
} else {
fullStyledSentence.setSpan(wrongColor, start, start + quoteWords[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.i("AzureSpeechRecognition", "word number " + i + "is wrong");
}
mQuoteBodyTextView.setText(null); //to delete repeatedly appended text
mQuoteBodyTextView.append(fullStyledSentence + " ");
}
}
But the resulted text isn't colored and they are glued together with no spaces.
答案1
得分: 2
似乎 `ForegroundColorSpan`/`BackgroundColorSpan` 不可重用,每次我们都需要实例化一个新的。不管怎样,我认为使用 `SpannableString` 更好,就像下面这样:
```java
public class MainActivity extends AppCompatActivity {
// 将所有空白替换为单个空格
private String quote = "我想要用绿色标记正确的单词".replaceAll("\\s+", " ");
private String result = "我想要用蓝色标记正确的单词".replaceAll("\\s+", " ");
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] quoteWords = quote.split("\\s");
String[] resultWords = result.split("\\s");
SpannableString spannableQuote = new SpannableString(quote);
if (quoteWords.length == resultWords.length) {
int index = 0;
for (int i = 0; i < quoteWords.length; i++) {
spannableQuote.setSpan(
new BackgroundColorSpan(quoteWords[i].equals(resultWords[i]) ? Color.GREEN : Color.RED),
index,
index + quoteWords[i].length(),
SpannableString.SPAN_INCLUSIVE_INCLUSIVE
);
index += quoteWords[i].length() + 1; // 1 用于单词之间的空格
}
}
((TextView) findViewById(R.id.textView1)).setText(result);
((TextView) findViewById(R.id.textView2)).setText(spannableQuote);
}
}
结果:
```
英文:
It seems that ForegroundColorSpan
/BackgroundColorSpan
are not reusable and each time we should instantiate a new one. Anyway, I think it makes sense better to write it using SpannableString
like the following:
public class MainActivity extends AppCompatActivity {
// replacing all whitespaces with single space
private String quote = "I want to color the correct word with green".replaceAll("\\s+", " ");
private String result = "I want to color the right word with blue".replaceAll("\\s+", " ");
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] quoteWords = quote.split("\\s");
String[] resultWords = result.split("\\s");
SpannableString spannableQuote = new SpannableString(quote);
if (quoteWords.length == resultWords.length) {
int index = 0;
for (int i = 0; i < quoteWords.length; i++) {
spannableQuote.setSpan(
new BackgroundColorSpan(quoteWords[i].equals(resultWords[i]) ? Color.GREEN : Color.RED),
index,
index + quoteWords[i].length(),
SpannableString.SPAN_INCLUSIVE_INCLUSIVE
);
index += quoteWords[i].length() + 1; // 1 for the space between words
}
}
((TextView) findViewById(R.id.textView1)).setText(result);
((TextView) findViewById(R.id.textView2)).setText(spannableQuote);
}
}
<br/>
Result:
<tr>
<td><img src="https://i.stack.imgur.com/P0Cn0.png" width="300"/></td>
</tr>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论