如何在 addTextChangedListener 中使用 spannable 字符串来更改 editText 子字符串的颜色?
How to use spannable strings in addTextChangedListener to change color of editText substring?
我正在尝试实现类似于自动突出显示关键字的代码编辑器的功能。我将有一个字符串数组,当用户键入文本并且它与字符串数组中的字符串匹配时,我想更改 editText 字符串的颜色和字体。我正在使用 addTextChangeListener 但整个 editText 的文本发生了变化。我只希望匹配的词是 highlighted.I 明白我必须使用 spannable 字符串但是代码崩溃了。任何人都可以帮助我正确使用 addTextChangedListener() 的 spannable 字符串吗?
这是我的代码:
editText.addTextChangedListener(new TextWatcher() {
private SpannableString spanString;
private ForegroundColorSpan span;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
spanString = new SpannableString(s);
span = new ForegroundColorSpan(Color.YELLOW);
spanString.setSpan(span, start, start + count, 0);
}
@Override
public void afterTextChanged(Editable s) {
int beginIdx = spanString.getSpanStart(s);
int endIdx = spanString.getSpanEnd(s);
if(s.subSequence(beginIdx, endIdx).equals("for"))
{
editText.setText(spanString, EditText.BufferType.SPANNABLE);
}
spanString.removeSpan(span);
span = null;
spanString = null;
}
});
通过调用 editText.setTextColor(getResources().getColor(R.color.indigo));
,您可以设置整个 editText 的颜色。
您必须设置关键字范围的颜色(在本例中为“for”关键字)。
为此,您必须知道关键字在字符串中的位置(关键字的开始和结束索引)。那么就可以这样设置了。
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().contains("for"))
{
Spannable wordToSpan = new SpannableString("for");
wordToSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.indigo), START_INDEX_OF_THE_KEYWORD_IN_THE_STRING, END_INDEX_OF_THE_KEYWORD_IN_THE_STRING, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(wordToSpan);
}
}
});
由于设置跨度需要调用 setText,还请注意您需要防止无限循环...
ms1996 我知道您正在尝试创建 IDE。要突出显示代码代码的语法,您应该使用 spannable String 或使用任何库来使其更容易。此外,您可以尝试此代码:
I created simple code for highlight syntax in EditText. First i created a HashMap to store keywords and colors.
Map<String,Integer> map = new HashMap<>();
map.put("public",Color.CYAN);
map.put("void", Color.BLUE);
map.put("String",Color.RED);
然后我为 EditText 添加了一个 TextWatcher。在 afterTextChanged 方法中,我使用以下代码为每个关键字设置颜色,
........
@Override
public void afterTextChanged(Editable editable) {
String string = editable.toString();
String[] split = string.split("\s");
for(int i = 0 ; i < split.length ; i++){
String s = split[i];
if(map.containsKey(s)){
int index = string.indexOf(s);
int color = map.get(s);
editable.setSpan(new ForegroundColorSpan(color),
index,
index + s.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
试试这个,问任何问题。您可以更改任何文本的颜色,只需将“for”替换为所需的文本并替换颜色 -
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String string = s.toString();
if (string.contains("for")) {
//Count to change color of all the "for"
int count = (string.length() - string.replaceAll("for", "").length())/3;
//You can make these global
int start = 0;
int beginIdx = 0;
int endIdx = 0;
for (int i = 0; i < count; i++) {
beginIdx = string.indexOf("for", start);
endIdx = beginIdx + 3;
start = endIdx;
if (beginIdx > 0)
s.setSpan(new ForegroundColorSpan(Color.GREEN),//ContextCompat.getColor(getContext(), R.color.indigo)
beginIdx, endIdx, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
});
我正在尝试实现类似于自动突出显示关键字的代码编辑器的功能。我将有一个字符串数组,当用户键入文本并且它与字符串数组中的字符串匹配时,我想更改 editText 字符串的颜色和字体。我正在使用 addTextChangeListener 但整个 editText 的文本发生了变化。我只希望匹配的词是 highlighted.I 明白我必须使用 spannable 字符串但是代码崩溃了。任何人都可以帮助我正确使用 addTextChangedListener() 的 spannable 字符串吗? 这是我的代码:
editText.addTextChangedListener(new TextWatcher() {
private SpannableString spanString;
private ForegroundColorSpan span;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
spanString = new SpannableString(s);
span = new ForegroundColorSpan(Color.YELLOW);
spanString.setSpan(span, start, start + count, 0);
}
@Override
public void afterTextChanged(Editable s) {
int beginIdx = spanString.getSpanStart(s);
int endIdx = spanString.getSpanEnd(s);
if(s.subSequence(beginIdx, endIdx).equals("for"))
{
editText.setText(spanString, EditText.BufferType.SPANNABLE);
}
spanString.removeSpan(span);
span = null;
spanString = null;
}
});
通过调用 editText.setTextColor(getResources().getColor(R.color.indigo));
,您可以设置整个 editText 的颜色。
您必须设置关键字范围的颜色(在本例中为“for”关键字)。 为此,您必须知道关键字在字符串中的位置(关键字的开始和结束索引)。那么就可以这样设置了。
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().contains("for"))
{
Spannable wordToSpan = new SpannableString("for");
wordToSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.indigo), START_INDEX_OF_THE_KEYWORD_IN_THE_STRING, END_INDEX_OF_THE_KEYWORD_IN_THE_STRING, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(wordToSpan);
}
}
});
由于设置跨度需要调用 setText,还请注意您需要防止无限循环...
ms1996 我知道您正在尝试创建 IDE。要突出显示代码代码的语法,您应该使用 spannable String 或使用任何库来使其更容易。此外,您可以尝试此代码:
I created simple code for highlight syntax in EditText. First i created a HashMap to store keywords and colors.
Map<String,Integer> map = new HashMap<>();
map.put("public",Color.CYAN);
map.put("void", Color.BLUE);
map.put("String",Color.RED);
然后我为 EditText 添加了一个 TextWatcher。在 afterTextChanged 方法中,我使用以下代码为每个关键字设置颜色,
........
@Override
public void afterTextChanged(Editable editable) {
String string = editable.toString();
String[] split = string.split("\s");
for(int i = 0 ; i < split.length ; i++){
String s = split[i];
if(map.containsKey(s)){
int index = string.indexOf(s);
int color = map.get(s);
editable.setSpan(new ForegroundColorSpan(color),
index,
index + s.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
试试这个,问任何问题。您可以更改任何文本的颜色,只需将“for”替换为所需的文本并替换颜色 -
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String string = s.toString();
if (string.contains("for")) {
//Count to change color of all the "for"
int count = (string.length() - string.replaceAll("for", "").length())/3;
//You can make these global
int start = 0;
int beginIdx = 0;
int endIdx = 0;
for (int i = 0; i < count; i++) {
beginIdx = string.indexOf("for", start);
endIdx = beginIdx + 3;
start = endIdx;
if (beginIdx > 0)
s.setSpan(new ForegroundColorSpan(Color.GREEN),//ContextCompat.getColor(getContext(), R.color.indigo)
beginIdx, endIdx, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
});