Android Development: How To Replace Part of an EditText with a Spannable

后端 未结 2 1583
误落风尘
误落风尘 2020-12-10 15:20

I\'m trying to replace part of an Editable returned from getText() with a span.

I\'ve tried getText().replace() but that\'s on

相关标签:
2条回答
  • 2020-12-10 15:35

    I answered a smilar question recently: How to use SpannableString with Regex in android?. But I'll add a copy of that answer.

    Here's a class that will help you:

    public class Replacer {
        private final CharSequence mSource;
        private final CharSequence mReplacement;
        private final Matcher mMatcher;
        private int mAppendPosition;
        private final boolean mIsSpannable;
    
        public static CharSequence replace(CharSequence source, String regex,
                CharSequence replacement) {
    
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(source);
            return new Replacer(source, matcher, replacement).doReplace();
        }
    
        private Replacer(CharSequence source, Matcher matcher,
                CharSequence replacement) {
            mSource = source;
            mReplacement = replacement;
            mMatcher = matcher;
            mAppendPosition = 0;
            mIsSpannable = replacement instanceof Spannable;
        }
    
        private CharSequence doReplace() {
            SpannableStringBuilder buffer = new SpannableStringBuilder();
            while (mMatcher.find()) {
                appendReplacement(buffer);
            }
            return appendTail(buffer);
        }
    
        private void appendReplacement(SpannableStringBuilder buffer) {
            buffer.append(mSource.subSequence(mAppendPosition, mMatcher.start()));
            CharSequence replacement = mIsSpannable
                    ? copyCharSequenceWithSpans(mReplacement)
                    : mReplacement;
            buffer.append(replacement);
    
            mAppendPosition = mMatcher.end();
        }
    
        public SpannableStringBuilder appendTail(SpannableStringBuilder buffer) {
            buffer.append(mSource.subSequence(mAppendPosition, mSource.length()));
            return buffer;
        }
    
        // This is a weird way of copying spans, but I don't know any better way.
        private CharSequence copyCharSequenceWithSpans(CharSequence string) {
            Parcel parcel = Parcel.obtain();
            try {
                TextUtils.writeToParcel(string, parcel, 0);
                parcel.setDataPosition(0);
                return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
            } finally {
                parcel.recycle();
            }
        }
    }
    

    And an example of usage:

    CharSequence modifiedText = Replacer.replace("ABC aaa AB ABC aa ad ABC", "ABC",
        Html.fromHtml("<font color=\"red\">CBA</font>"));
    textView.setText(modifiedText);
    
    0 讨论(0)
  • 2020-12-10 15:38

    This minimal size example makes the word 'first' large:

    public class SpanTest extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            String dispStr = "I'm the first line\nI'm the second line";
            TextView tv = (TextView) findViewById(R.id.textView1);
            int startSpan = dispStr.indexOf("first");
            int endSpan = dispStr.indexOf("line");
            Spannable spanRange = new SpannableString(dispStr);
            TextAppearanceSpan tas = new TextAppearanceSpan(this, android.R.style.TextAppearance_Large);
            spanRange.setSpan(tas, startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            tv.setText(spanRange);
        }
    }
    

    You can adapt it to your needs

    0 讨论(0)
提交回复
热议问题