Android EditText : How to apply Foreground color s

2020-03-03 06:15发布

问题:

I'm trying to apply a font color to text in an EditText as you type text. However, its just very inconsistent, meaning that sometimes if you type a space, the text preceding that space will go back to the default black color. Or if I put my cursor in the middle of a word and start typing the entire word changes color and not just the text I'm typing. The bold, italic and underline seem to work well though. How can I guarantee that only the text I'm typing will be affected with regards to font color?

See "SIZE AND COLOR" comment below...

     contentEdit.addTextChangedListener(new TextWatcher() { 
            public void afterTextChanged(Editable s) { 

                //add style as the user types if a toggle button is enabled
                ToggleButton boldButton = (ToggleButton) findViewById(R.id.bold);
                ToggleButton emButton = (ToggleButton) findViewById(R.id.italic);
                ToggleButton underlineButton = (ToggleButton) findViewById(R.id.underline);

                int position = Selection.getSelectionStart(contentEdit.getText());

                try{
                    if (position < 0){
                        position = 0;
                    }

                    if (position > 0){

                        if (styleStart > position || position > (cursorLoc + 1)){
                            //user changed cursor location, reset
                            if (position - cursorLoc > 1){
                                //user pasted text
                                styleStart = cursorLoc;
                            }
                            else{
                                styleStart = position - 1;
                            }
                        }

                        if (boldButton.isChecked()){  
                            StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class);

                            for (int i = 0; i < ss.length; i++) {
                                if (ss[i].getStyle() == android.graphics.Typeface.BOLD){
                                    s.removeSpan(ss[i]);
                                }
                            }
                            s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                        if (emButton.isChecked()){
                            StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class);

                            for (int i = 0; i < ss.length; i++) {
                                if (ss[i].getStyle() == android.graphics.Typeface.ITALIC){
                                    s.removeSpan(ss[i]);
                                }
                            }
                            s.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                        if (underlineButton.isChecked()){
                            UnderlineSpan[] ss = s.getSpans(styleStart, position, UnderlineSpan.class);

                            for (int i = 0; i < ss.length; i++) {
                                s.removeSpan(ss[i]);
                            }
                            s.setSpan(new UnderlineSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }

                        //SIZE AND COLOR//////////////////////////////////////////////////////
                       s.setSpan(new ForegroundColorSpan(m_color), position, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                       s.setSpan(new AbsoluteSizeSpan(m_curSize, true), position, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
                }
                catch(Exception e){
                    //Toast.makeText(m_ctx, m_ctx.gets, Toast.LENGTH_LONG).show();
                    showMessage(R.string.NOTE_WARNING_STYLE,m_utils.MSGTYPE_WARNING);
                }

                cursorLoc = Selection.getSelectionStart(contentEdit.getText());
            }

回答1:

You can use pattern for finding words and then apply any span to words.

@Override
public void afterTextChanged(Editable s) {
    Spannable textSpan = s;
    final Pattern pattern = Pattern.compile("\\w+");
    final Matcher matcher = pattern.matcher(textSpan);
    while (matcher.find()) {
        start = matcher.start();
        end = matcher.end();
        textSpan.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.red)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    }

That's it. it will highlight all matching words you typing. Hope it help.



回答2:

I changed the start of the Spannable from position to position - 1:

//Color
s.setSpan(new ForegroundColorSpan(m_color), 
          position-1, 
          position, 
          Spannable.SPAN_INCLUSIVE_INCLUSIVE);
//Size
s.setSpan(new AbsoluteSizeSpan(m_curSize, true), 
          position-1, 
          position, 
          Spannable.SPAN_INCLUSIVE_INCLUSIVE);


回答3:

like so....

public static SpannableString parseActiveReply(String name, String body) {
    SpannableString sp = new SpannableString(name + " " + body);
    // 设置用户名字体加粗、高亮
    sp.setSpan(new ForegroundColorSpan(Color.parseColor("#5FADC7")), 0,
            name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    // sp.setSpan(new ForegroundColorSpan(Color.parseColor("#5FADC7")), 0,
    // 0,
    // Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return sp;
}