简体   繁体   English

Android 中 EditText 的不同颜色

[英]Different colors at EditText in Android

I am trying to make the text of an EditText multiple colors.我正在尝试使 EditText 的文本具有多种颜色。 For example, if my text is, "It is a good day.", is it possible to make the "It is a" part of the sentence green and the rest red?例如,如果我的文字是,“It is a good day.”,是否可以将句子的“It is a”部分设为绿色,其余部分设为红色?

I use something like that to make some parts of my color green: 我使用类似的东西来制作我的颜色的一些部分:

final String text = "Some Text";
Spannable modifiedText = new SpannableString(text);
modifiedText.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.green)), 0, lengthYouWant, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(modifiedText);

You could use spannables . 你可以使用spannables

Spannable spannable = yourText.getText();
spannable .setSpan(new BackgroundColorSpan(Color.argb(a, r, g, b)), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

Yes. 是。 You will need to create a Spannable object (either a SpannedString or SpannedStringBuilder ), then set spans upon it to apply the colors you seek. 您将需要创建一个Spannable对象( SpannedStringSpannedStringBuilder ),然后设置跨度以应用您寻找的颜色。

For example, the following method from this sample project takes the contents of a TextView , searches for a user-entered string, and marks up all occurrences with a purple background color, removing all previous markers: 例如, 此示例项目中的以下方法获取TextView的内容,搜索用户输入的字符串,并使用紫色背景颜色标记所有实例 ,删除所有先前的标记:

  private void searchFor(String text) {
    TextView prose=(TextView)findViewById(R.id.prose);
    Spannable raw=new SpannableString(prose.getText());
    BackgroundColorSpan[] spans=raw.getSpans(0,
                                             raw.length(),
                                             BackgroundColorSpan.class);

    for (BackgroundColorSpan span : spans) {
      raw.removeSpan(span);
    }

    int index=TextUtils.indexOf(raw, text);

    while (index >= 0) {
      raw.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
          + text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      index=TextUtils.indexOf(raw, text, index + text.length());
    }

    prose.setText(raw);
  }

In your case, changing the foreground color would use a ForegroundColorSpan instead of a BackgroundColorSpan . 在您的情况下,更改前景色将使用ForegroundColorSpan而不是BackgroundColorSpan

Things get a bit tricky with an EditText , in that the user can edit the text, and you will need to choose your flags to meet the rules you want. 使用EditText会让事情变得有点棘手, EditText用户可以编辑文本,您需要选择符号来满足您想要的规则。 For example, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE would say that: 例如, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE会说:

  • characters entered in the middle of the spanned area get the span's effect (eg, foreground color) 在跨区域中间输入的字符获得跨度效果(例如,前景色)
  • characters entered immediately before or after the spanned area are considered outside the spanned area and therefore do not get the span's effect 在跨区域之前或之后立即输入的字符被认为是在跨区域之外,因此不会获得跨度的效果

I'm have this trouble too. 我也有这个麻烦。 After several hours, I figured out how to handle it: 几个小时后,我想出了如何处理它:

  mYourTextView.addTextChangedListener(new TextWatcher() {

        private String oldContent = "";

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            final String newContent = mYourTextView.getText().toString();

            if (newContent.length() > 10 && !oldContent.equals(newContent)) {
                oldContent = newContent;
                mYourTextView.setText(Html.fromHtml(
                        String.format("%s", "<font color='#000000'>" + newContent.substring(0, 10) + "</font>")
                                + "<font color='#ff0000'>" + newContent.substring(10, newContent.length()) + "</font>"));
                Log.d("onTextChanged", "Start : " + start);

                //move cursor after current character
                mYourTextView.setSelection(start + 1 > mYourTextView.getText().toString().length()
                        ? start : start + 1);

            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

This code make first 10 characters in black color and the followed characters in red color. 此代码使前10个字符为黑色,后面的字符为红色。 We need variable oldContent to prevent loop infinity because when EditText call setText() then onTextChanged 我们需要变量oldContent来防止循环无穷大,因为当EditText调用setText()然后onTextChanged时

Just to elaborate on the answer of WarrenFaith:只是详细说明 WarrenFaith 的回答:

implement a TextWatcher实现一个 TextWatcher

yourEditText.onFocusChangeListener = this

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable?) {
    val newTextStyle: Spannable = SpannableString(s?.toString())
    resources.getColor(R.color.color_w3w, requireActivity().theme)
    val span = ForegroundColorSpan(resources.getColor(R.color.your_color_here, requireActivity().theme))
    newTextStyle.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)//Will set the first three characters to 'R.color.your_color_here'
    s?.set(0, 3, span)
}

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

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