Как android span действует на входные символы в EditText

Я хочу реализовать эффект, который управляет входными символами в тексте редактирования, независимо от того, используется ли диапазон.

Например, в EditText можно использовать

getEditableText().setSpan(new StyleSpan(Typeface.NORMAL), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

сделайте выбранные символы ЖИРНЫМИ. Есть решения, которые, когда пользователь включает настройку полужирного шрифта, каждый введенный символ с тех пор будет выделен жирным шрифтом, и как только пользователь отключит настройку полужирного шрифта, символы, введенные после этого, не будут выделены жирным шрифтом.

Я попытался использовать Spanned.SPAN_EXCLUSIVE_INCLUSIVE в качестве флагов в SpannableStringBuilder.setSpan(), но я просто могу контролировать, когда начинается эффект span, и не могу контрольный конец.

Также попытался использовать TextWatcher для прослушивания ввода каждого символа и установить Span для каждого символа.

 @Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter)
{
    setTextSpan(start, lengthBefore, lengthAfter);
}

private void setTextSpan(int start, int lengthBefore, int lengthAfter)
{
    if (isBold) {
        getEditableText().setSpan(new StyleSpan(Typeface.BOLD), start, start + lengthAfter, Spanned
                .SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

но при использовании Html.toHtml() каждый символ будет заключен в <b></b>.

Нравится<p dir="ltr"><b>1</b><b>1</b><b>1</b><b>1</b><b>1</b><b>1</b></p>

Я прочитал некоторый исходный код в SpannableStringBuilder.java, но не нашел никакого метода для изменения области действия span.

Надеюсь, кто-то может дать мне несколько предложений. Заранее спасибо.


person nebulae-pan    schedule 10.05.2016    source источник
comment
Как насчет TextWatcher, который вы использовали, в чем проблема?   -  person Huo Chhunleng    schedule 10.05.2016
comment
@Huo Chhunleng Извините, что отвечаю так поздно. Проблема в том, что когда я использую TextWatcher и ввожу некоторые символы, отображение правильное, но после преобразования с помощью Html.toHtml() результат не Это не то, что я хочу. Например, ввод: abdce, после преобразования я получу '‹p dir=ltr›‹b›a‹/b›‹b›b‹/b›‹b›c‹/b› ‹b›d‹/b›‹b›e‹/b›‹/p›’, но мне нужен результат '‹p dir=ltr›‹b›abcde‹/b›‹/p›'   -  person nebulae-pan    schedule 10.05.2016
comment
@Huo Chhunleng Таким образом, просто можно выделить выделенный текст жирным шрифтом. Я хочу, чтобы при включении жирного шрифта все символы, вводимые после, были жирными, а при отключении жирного шрифта ввод был нормальным.   -  person nebulae-pan    schedule 11.05.2016
comment
Извините, что прерываю вас, вы решили проблему? Или найти другой способ достижения? Если да, то большое спасибо за ответ.   -  person Gallery    schedule 14.03.2018


Ответы (2)


Были найдены некоторые полезные советы, вы можете проверить 'Android EditText: как применять интервалы при составлении?'.

Но есть и другой вопрос: Хорошо работает флаг 'SPAN_INCLUSIVE_INCLUSIVE', устанавливающий шрифт BOLD. Но когда я переключаюсь, чтобы установить шрифт НЕ ЖИРНЫМ (просто вернусь к нормальному), вставленный текст по-прежнему остается ЖИРНЫМ. Я не знаю, как решить эту проблему.

person Gallery    schedule 15.03.2018
comment
Привет, я уже прочитал упомянутый вами ответ, это решение может решить некоторые проблемы, но ситуация, с которой я столкнулся, более сложная. Наконец я придумал два решения. Я опишу их в своем ответе. - person nebulae-pan; 16.03.2018

Прежде всего, установите TextWatcher для EditText. Тогда есть два решения.
1. когда текст изменился, если вводится символ, используйте removeSpan(), затем используйте setSpan() для сброса диапазона диапазона.
2. Используйте отражение. SpannableStringBuilder имеет вызов элемента mSpanEnds, этот массив записывает информацию о положении для всего диапазона в SpannableStringBuilder, используйте отражение изменения его значения.
У меня есть пример для решения 2, в этом примере могут быть некоторые ошибки, но он хорошо работает при применении пролеты.

person nebulae-pan    schedule 16.03.2018