Java 如何在Android中为edittext中写入的每个字符设置不同的颜色?

Java 如何在Android中为edittext中写入的每个字符设置不同的颜色?,java,android,android-edittext,Java,Android,Android Edittext,我正在尝试使用不同的颜色对edittext中编写的字符进行着色。 例如,我希望“a”在edittext中写入时始终保持红色,而其他的则保持黑色。至少有可能吗 我在edittext中找到了一些关于颜色设置的答案,如下所示,但这都是关于开始索引和结束索引范围内的颜色设置 **示例** final String text = "for example"; Spannable modifiedText = new SpannableString(text); modifiedText.setSpan(n

我正在尝试使用不同的颜色对
edittext
中编写的字符进行着色。 例如,我希望“a”在
edittext
中写入时始终保持红色,而其他的则保持黑色。至少有可能吗

我在
edittext
中找到了一些关于颜色设置的答案,如下所示,但这都是关于开始索引和结束索引范围内的颜色设置

**示例**

final String text = "for example";
Spannable modifiedText = new SpannableString(text);
modifiedText.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.red)), 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(modifiedText);

一种方法是使用
Html.fromHtml(String)
并使用
Map
将字体颜色设置为预定义的颜色。e、 g

private static final String FONT_REPLACEMENT = "<font color='%1$s'>%2$s</font>";
private static final String DEFAULT_COLOR = "#FAFAFA";

public Spanned convertToHtml(String text, Map<String, String> colorSets){
    String altered = "<![CDATA[";

    for(int i = 0; i < text.length(); i++) {
        String value = String.valueOf(text.charAt(i));
        String color = colorSets.get(value.toLowerCase(Locale.US));

        if(color == null)
            color = DEFAULT_COLOR;

        altered += String.format(FONT_REPLACEMENT, color, value);
    }

    return Html.fromHtml(altered + "]]>");
}
private static final String FONT_REPLACEMENT=“%2$s”;
私有静态最终字符串默认值_COLOR=“#FAFAFA”;
公共跨域转换HTML(字符串文本、地图颜色集){
字符串=”);
}
然后使用它,你可以做如下事情:

Map<String, String> colors = new HashMap<String, String();
colors.put("a", "#FF0000");
colors.put("b", "#00FF00");
colors.put("c", "#0000FF");
....

textView.setText(convertToHtml("for example", colors));

Map colors=newhashmap是的,这是可能的,但我不知道在性能方面是否太贵。
您可以使用TextWatcher根据您的字符颜色映射为最后插入的字符上色

public class MainActivity extends AppCompatActivity {
    private SpannableStringBuilder mSpannableStringBuilder;
    private EditText mEditText;
    private static final Map<String, Integer> COLORS_MAP = new HashMap<>();

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // here you can populate your map with colors
        COLORS_MAP.put("a", Color.RED);
        COLORS_MAP.put("b", Color.GREEN);
        COLORS_MAP.put("c", Color.BLUE);
        COLORS_MAP.put("d", Color.MAGENTA);

        mSpannableStringBuilder = new SpannableStringBuilder();

        mEditText = (EditText) findViewById(R.id.editText);
        mEditText.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.length() > 0) {

                    // unregister and register the listener to avoid infinite loop
                    mEditText.removeTextChangedListener(this);

                    int start = s.length() - 1;
                    String lastChar = s.toString().substring(start);

                    SpannableString lastSpannableChar = new SpannableString(lastChar);

                    // pick the color based on the last char
                    int color = pickColorByChar(lastChar);

                    // Span to set char color
                    ForegroundColorSpan fcs = new ForegroundColorSpan(color);

                    // Set the text color for the last character
                    lastSpannableChar.setSpan(fcs, 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

                    // append the last char to the string builder so you can keep the previous span
                    mSpannableStringBuilder.append(lastSpannableChar);

                    mEditText.setText(mSpannableStringBuilder);
                    mEditText.setSelection(mEditText.getText().length()); //this is to move the cursor position

                    mEditText.addTextChangedListener(this);

                }
            }
        });
    }

    public int pickColorByChar(String aChar){
        return COLORS_MAP.get(aChar);
    }
}
public类MainActivity扩展了AppCompatActivity{
私人SpannableStringBuilder mSpannableStringBuilder;
私有EditText-mEditText;
私有静态最终映射颜色_Map=new HashMap();
@在创建时覆盖受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在这里,您可以使用颜色填充地图
颜色(a,颜色,红色),;
颜色(b,颜色,绿色),;
颜色(c,Color.BLUE);;
颜色(MAP.put)("d",颜色,洋红);;
mSpannableStringBuilder=新的SpannableStringBuilder();
mEditText=(EditText)findViewById(R.id.EditText);
mEditText.addTextChangedListener(新的TextWatcher(){
@凌驾
更改前文本之前的公共void(字符序列s、int start、int count、int after){
}
@凌驾
public void onTextChanged(字符序列、int start、int before、int count){
}
@凌驾
公共无效后文本已更改(可编辑){
如果(s.长度()>0){
//取消注册并注册侦听器以避免无限循环
mEditText.removeTextChangedListener(此);
int start=s.length()-1;
字符串lastChar=s.toString().substring(开始);
SpannableString lastSpannableChar=新的SpannableString(lastChar);
//根据最后一个字符选择颜色
int color=pickColorByChar(lastChar);
//设置字符颜色的范围
ForegroundColorSpan fcs=新的ForegroundColorSpan(颜色);
//设置最后一个字符的文本颜色
lastSpannableChar.setSpan(fcs,0,1,Spannable;
//将最后一个字符附加到字符串生成器中,以便保留上一个跨度
mSpannableStringBuilder.append(lastSpannableChar);
mEditText.setText(mSpannableStringBuilder);
mEditText.setSelection(mEditText.getText().length());//这是为了移动光标位置
mEditText.addTextChangedListener(此);
}
}
});
}
public int pickColorByChar(字符串aChar){
返回颜色\u MAP.get(aChar);
}
}
这就是结果


是的,这是在textview内部使用Spanable进行着色的好方法,要获取索引,您需要使用方法获取“a”的索引谢谢您的回答。然而,我要寻找的是根据特定字符选择颜色的方法,这样每当键入“a”时,它就会变成红色。例如,在下面的示例中,除了索引之外,只有三个红色字母。例如,“我有一个苹果。”@lifeBalkan只需制作一张
地图
,其中字符是关键,整数是颜色。使用
TextWatcher
并在添加(或替换)文本时,将
ForegroundColorSpan
s适当地添加到新文本中。谢谢,但它不起作用。我想在recyclerview中更改这些。因此,在bindView保持方法中添加了上述代码。**public void onBindViewHolder(final SimpleViewHolder viewHolder,final int position){Map colors=new HashMap();colors.put(“*”,“#ffffff”);viewHolder.pwInput.setText(convertToHtml(myDatasetCopy.get(position.getPwInput(),colors));…},并且在与上述相同的类中有“convertToHtml”方法(在适配器中)。**私有静态最终字符串FONT_REPLACEMENT=“%2$s”;私有静态最终字符串默认值_COLOR=“#000000”;公共范围的convertToHtml(字符串文本,映射颜色集){}字符串更改=”);**我在这里得到的是‘在这些评论中很难诊断问题,但是如果字体颜色是默认的,很可能颜色没有正确添加到地图中。每个字母都需要有一个定义的颜色,否则它将默认为默认的_颜色或您在上面发布的convertToHtml()方法中选择的任何颜色<代码>颜色。放置(“*”,“#ffffff”)
不会更改所有字符,这只会将*字符的颜色具体更改为#FFFDo我需要在“/”中添加一些内容,以获取最后一个字符并根据设置的字符颜色更改颜色“?因为它不工作与上述代码只。我更新了我的答案与更多的代码。现在,示例应该是您所问的;)是的!非常感谢您的建议和示范!