简体   繁体   English

如何在 addTextChangedListener 中使用可扩展字符串来更改 editText substring 的颜色?

[英]How to use spannable strings in addTextChangedListener to change color of editText substring?

I am trying to implement something similar to a code editor where keywords are automatically highlighted.我正在尝试实现类似于自动突出显示关键字的代码编辑器。 I am going to have a string array and I want to change the color and font of the editText string when the user types the text and it matches a string from the string array.我将有一个字符串数组,当用户键入文本并且它与字符串数组中的字符串匹配时,我想更改 editText 字符串的颜色和字体。 I am using the addTextChangeListener but the text of the whole editText changes.我正在使用 addTextChangeListener 但整个 editText 的文本发生了变化。 I want just the matched word to be highlighted.I understand I have to use spannable strings but the code crashes.我只想突出显示匹配的单词。我知道我必须使用可扩展的字符串,但代码会崩溃。 Can anyone help me with the correct usage of spannable strings with addTextChangedListener()?任何人都可以通过 addTextChangedListener() 帮助我正确使用可扩展字符串吗? Here is my code:这是我的代码:

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;
            }
        });

ms1996 I know you are trying to create IDE. ms1996 我知道您正在尝试创建 IDE。 To highlight the syntax of codes codes you should use spannable String or use any library to get it easier.要突出代码代码的语法,您应该使用 spannable String 或使用任何库来使其更容易。 Moreover you can try this code:此外,您可以尝试以下代码:

                    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);

Then I added a TextWatcher for the EditText.然后我为 EditText 添加了一个 TextWatcher。 In afterTextChanged method I used following code to set colors to each keyword,在 afterTextChanged 方法中,我使用以下代码将 colors 设置为每个关键字,

                    ........
                    @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);
                            }

                        }
                    }

By calling editText.setTextColor(getResources().getColor(R.color.indigo));通过调用editText.setTextColor(getResources().getColor(R.color.indigo)); you are setting the color for the whole editText.您正在为整个 editText 设置颜色。

You have to set the color of the span of your keyword (in this case "for" keyword).您必须设置关键字跨度的颜色(在本例中为“for”关键字)。 To do this, you have to know the position of the keyword in the string (starting and ending index of the keyword).为此,您必须知道字符串中关键字的 position(关键字的开始和结束索引)。 Then it can be set like this.然后可以这样设置。

    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);
            }
        }
    });

Since setting a span requires calling a setText also be aware that you need to protect against infinite loop...由于设置跨度需要调用 setText 还请注意,您需要防止无限循环......

Try this, ask for any query.试试这个,询问任何问题。 You can change color any text, just replace the "for" with desired text and replace the color -您可以更改任何文本的颜色,只需将“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);

                    }

                }
            }
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM