Объясните значение флажков Span, таких как SPAN_EXCLUSIVE_EXCLUSIVE

Может ли кто-нибудь четко объяснить примерами, что означает каждый флажок span > , например SPAN_EXCLUSIVE_EXCLUSIVE и SPAN_MARK_MARK, и когда использовать флагов?

Я не понимаю официальную документацию, когда она говорит:

Пролисты типа SPAN_EXCLUSIVE_EXCLUSIVE не расширяются, чтобы включать текст вставлены либо в их начальную, либо конечную точку.

Включается ли "expand to include" в редактирование, сделанное после вставки пролетов?

Означает ли это, что эти флаги НЕ влияют на Spannables с неизменяемым текстом?

Ответ 1

Включается ли "expand to include" в редактирование, сделанное после вставки пролетов?

Да. Предположим, например, что мы имеем следующее:

Подскочила белая лиса.

Если мы использовали SPAN_EXCLUSIVE_EXCLUSIVE на полужирном полу, и мы вставляем текст в середине пролета, он все же полужирный:

Подскочила быстрая коричневая лиса.

Однако, если мы вставляем текст в начале или в конце жирного шрифта, вставленный текст не является жирным шрифтом:

Вскочила настоящая белая лиса.

Если бы мы использовали SPAN_INCLUSIVE_EXCLUSIVE, тогда вставка текста в начале была бы включена как часть диапазона, и мы бы имели:

Подскочила действительно быстрая лиса.

Означает ли это, что эти флаги НЕ влияют на Spannables с неизменяемым текстом?

Я бы сказал, что они имеют ограниченное использование для неизменяемого текста. В основном, они будут использоваться с SpannableStringBuilder или вещами, которые используют один под обложками (например, EditText).

Ответ 2

Что не значат флаги

Когда я впервые увидел части INCLUSIVE и EXCLUSIVE флагов Spannable, я подумал, что они просто сказали, включает ли диапазон span начальную и конечную позиции индекса диапазона. Это неправда. Позвольте мне проиллюстрировать это на следующем примере.

String myString = "01234";
int start = 1;
int end = 3;
int spanFlag = Spannable.SPAN_INCLUSIVE_INCLUSIVE; // this is what is changing

SpannableString spannableString = new SpannableString(myString);
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, start, end, spanFlag);
textView.setText(spannableString);

Вот результаты:

SPAN_INCLUSIVE_INCLUSIVE

enter image description here

SPAN_INCLUSIVE_EXCLUSIVE

enter image description here

SPAN_EXCLUSIVE_INCLUSIVE

enter image description here

SPAN_EXCLUSIVE_EXCLUSIVE

enter image description here

Они все одинаковы! Флаги не влияют на промежуток. Интервал всегда включает символ в своем начальном индексе и исключает символ в конечном индексе.

Что на самом деле означают флаги

Части INCLUSIVE и EXCLUSIVE флагов Spannable фактически указывают, должен ли диапазон содержать текст, который вставляется в начальную или конечную позиции.

Вот модифицированный пример, чтобы проиллюстрировать это.

String myString = "01234";
int start = 1;
int end = 3;
int spanFlag = Spannable.SPAN_INCLUSIVE_INCLUSIVE; // this is what is changing

// set the span
SpannableStringBuilder spannableString = new SpannableStringBuilder(myString);
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, start, end, spanFlag);

// insert the text after the span has already been set
// (inserting at start index second so that end index doesn't get messed up)
spannableString.insert(end, "x");
spannableString.insert(start, "x");

textView.setText(spannableString);

Вот результаты после вставки x в конце и начала индексов:

SPAN_INCLUSIVE_INCLUSIVE

enter image description here

SPAN_INCLUSIVE_EXCLUSIVE

enter image description here

SPAN_EXCLUSIVE_INCLUSIVE

enter image description here

SPAN_EXCLUSIVE_EXCLUSIVE

enter image description here

Заметки

  • Во втором примере мне пришлось использовать SpannableStringBuilder потому что текст в SpannableString является неизменным, поэтому вы не можете вставить в него текст. Таким образом, флаги, как правило, не имеют смысла для SpannableString. Однако можно представить ситуацию, в которой промежутки из SpannableString копируются в SpannableStringBuilder или Editable, и оттуда флаги будут иметь значение.
  • Посмотрите этот ответ, чтобы SpannableString разницу между SpannableString, SpannableStringBuilder, Editable и другими.

Ответ 3

Значения String, которые мы храним как ресурс в XML файле в каталоге res/values, можно стилизовать с помощью методов, определенных в интерфейсе android.text.Spannable, поля, определенные в интерфейсе android.text.Spanned(Spannable - это подинтерфейс Spanned), с классом android.text.SpannableStringBuilder(SpannableStringBuilder является подклассом Spannable) и с классами, определенными в пакете android.text.style, особенно для android.text.style.ForegroundColorSpan и android.text.style.StyleSpan классы. Поскольку SpannableStringBuilder является подклассом Spannable, а Spannable является подынтерфейсом Spanned. Все поля интерфейса Spanned и полная реализация методов интерфейса Spannable существуют в классе SpannableStringBuilder.

1. Теперь, чтобы стилизовать текстовый ресурс, мы должны сначала получить его с идентификатором ресурса с помощью метода метода getString (int resource_id) из объекта Resources, чтобы получить объект Resources, связанный с подклассом Context, который мы вызываем методом getResources(). example-

String title= getResources(). GetString (R.string.string_title);

2. Теперь нам нужно создать объект SpannableStringBuilder с его открытым конструктором без параметров или любым другим открытым конструктором.

3.SpannableStringBuilder работает немного сложным образом. Мы можем добавить текст в SpannableStringBuilder с помощью одного из методов добавления. Некоторая часть текста, которую содержит SpannableStringBuilder, может быть помечена как составная, и только эта часть будет стилизована (с цветом, шрифтом и т.д.).), когда новый текст добавляется в объект SpannableStringBuilder при любом индексе, если новый текст также будет помечен как расширенный или нет, что определяется полями интерфейса Spanned. Мы вызываем метод setSpan (Object what, int start, int end, int flags), объявленный интерфейсом Spannable и реализованный классом SpannableStringBuilder. Вот что является объектом класса пакета android.text.style.StyleSpan. Этот объект определяет тип стиля, который мы хотим применить, flags - это одно из полей, определенных в интерфейсе Spanned, этот параметр flags указывает, когда новый текст добавляется в этот объект SpannableStringBuilder по любому индексу, если новый текст также будет помечен как составной или нет.

4. Различные классы пакета android.text.style.StyleSpan определяют разные стили, но на данный момент я знаю только одно использование класса android.text.style.StyleSpan и одно использование android.text.style.ForegroundColorSpan учебный класс. Один открытый конструктор класса StyleSpan принимает значение int, которое может быть значением одного из полей, определенных в классе android.graphics.Typeface(BOLD, BOLD_ITALIC, ITALIC, NORMAL). Поскольку эти имена полей предполагают, что они будут стилизовать текст как жирный или жирный, курсив или обычный. Для example-

StyleSpan style_span = новый StyleSpan (Typeface.ITALIC);

Один открытый конструктор класса ForegroundColorSpan принимает значение int, которое может быть любым шестнадцатеричным значением цвета argb или значением одного из полей, определенных в классе android.graphics.Color(BLACK, BLUE, CYAN, DKGRAY, GREY, GREEN, LTGRAY, MAGENTA, RED, TRANSPARENT, WHITE, YELLOW). Поскольку имена этих полей предполагают, что они окрашивают текст. Чтобы дать шестнадцатеричное значение цвета argb в качестве int для конструктора, мы начинаем шестнадцатеричное значение с 0X или 0x, Java затем автоматически преобразует шестнадцатеричное значение в его int-эквивалент. Для example-

ForegroundColorSpan fore_ground_color_Span = new ForegroundColorSpan (Color.RED);

5. В методе setSpan (Object what, int start, int end, int flags) начало и конец определяют начальный диапазон текста, который должен быть помечен как составной, start определяет индекс начальных символов, а end указывает индекс символа переданного символа окончания для example- для строки "01234"

новый SpannableStringBuilder ("01234"). setSpan (foreground_color_span, 1, 3, span_flag);

приведет к тому, что только 12 будут помечены как составные изначально, поэтому начальный символ - это "1", как указано начальным индексом, а конечный символ - это 2, как указано индексом (конец-1). Таким образом, если мы дадим одинаковое значение для начала и конца, то текст не будет покрыт изначально, а диапазон будет равен нулю, для приведенного выше примера, если оба начала и конца равны 1, тогда начальный символ равен 1, но конечный символ равен 0. Это не имеет смысла, в этом случае не будет текста, помеченного как натянутый изначально.

6. Теперь некоторые поля интерфейса Spanned работают, как описано ниже. Когда добавляется новый текст.......... SPAN_EXCLUSIVE_EXCLUSIVE не помечает любой текст, добавляемый перед начальным символом и после конечного символа, как составной, но помечает любой текст, добавляемый после начального символа или перед конечным символом SPAN_EXCLUSIVE_EXCLUSIVE является синонимом для SPAN_POINT_MARK, если он является составным, если диапазон равен нулю, что означает, что текст не помечен как составной изначально, то любой текст, добавляемый по любому индексу, не помечается как объединенный с этим флагом,

SPAN_EXCLUSIVE_INCLUSIVE не помечает любой текст, добавляемый перед начальным символом как составной, но помечает любой текст, добавляемый после начального символа или любой текст, добавляемый до или после конечного символа, как составной, согласно моим тестам, SPAN_EXCLUSIVE_INCLUSIVE является синонимом для SPAN_POINT_POINT, если диапазон равен нулю, что означает, что текст не был помечен как составной изначально, тогда любой текст, добавленный к любому индексу, не помечается как объединенный с этим флагом,

SPAN_INCLUSIVE_EXCLUSIVE не помечает любой текст, добавляемый перед конечным символом как составной, но помечает любой текст, добавляемый после или перед начальным символом, или любой текст, добавляемый после конечного символа, как составной, согласно моим тестам, SPAN_INCLUSIVE_EXCLUSIVE является синонимом для SPAN_MARK_MARK, если диапазон равен нулю, что означает, что текст не был помечен как составной изначально, тогда любой текст, добавленный к любому индексу, не помечается как объединенный с этим флагом,

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

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

7. Теперь мы можем добавить любой текст в наш объект SpannableStringBuilder с помощью одного из методов добавления или одного из методов вставки для example-

SpannableStringBuilder text = new SpannableStringBuilder();...... text.append(string_value); //append (CharSequence text) добавляет данную строку в конец //insert (int where, CharSequence tb) вставляет данную строку после символа, индекс которого равен (where-1)

Новый текст, вставленный в этот SpannableStringBuilder, будет помечен как "составной и стилизованный" или нет, будет зависеть от флага, который мы указали при предыдущем вызове метода setSpan (Object what, int start, int end, int flags).

8. Если мы хотим применить более одного стиля к тексту в объекте SpannableStringBuilder, то мы можем снова вызвать метод setSpan (Object what, int start, int end, int flags) и указать стиль для параметра what, и начало и конец должны быть стилизованы изначально, затем параметр flag, чтобы указать, как стиль должен вести себя при вставке любого нового текста. Здесь важно то, что когда мы вызываем метод span, указанный стиль сочетается с start, end и флагом, который не зависит от любого предыдущего вызова метода span, что означает, что каждый вызов метода span применяет стиль, который работает независимо от любого другого стиля, который также применяется к тому же тексту. Даже если мы снова применяем тот же стиль, но с новым объектом к параметру "what", этот стиль также работает независимо от ранее примененного того же стиля, только для изменить уже примененный стиль, чтобы указать тот же объект для параметра "что". Для example-

    TextView txv=(TextView)findViewById(R.id.textView9);
    String myString = "01234";
    Object ob;
    int start = 1;
    int end = 4;
    int spanFlag = Spannable.SPAN_INCLUSIVE_INCLUSIVE; 
    SpannableStringBuilder spannableString = new SpannableStringBuilder(myString);
    ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
    ob=foregroundSpan;
    spannableString.setSpan(foregroundSpan, start, end, spanFlag);
    txv.setText(spannableString);

Это приведет к тому, что txv имеет "01234", где часть "123" имеет красный цвет.

    end=3;
    spanFlag = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
    spannableString.setSpan(new StyleSpan(Typeface.BOLD), start, end, spanFlag);
    txv.setText(spannableString);

Это приведет к тому, что txv имеет "01234", где часть "123" имеет красный цвет, а часть "12" выделена жирным шрифтом (жирный) и красный, но "3" только красный, а не жирный из-за "конца" значение.

    spannableString.insert(end, "x");
    spannableString.insert(start, "x");
    txv.setText(spannableString);

Это приведет к тому, что txv будет иметь "0x12x34", где часть "x12x3" имеет красный цвет, а только "12x3" выделена жирным шрифтом, это произошло потому, что красный стиль был первоначально применен к тексту "123" с флагом SPAN_INCLUSIVE_INCLUSIVE, что означает любой текст после или до 1 и 3 всегда включаются в красную область стилей, следовательно, "x12x3" красного цвета, жирный стиль был первоначально применен к тексту "12" с флагом SPAN_EXCLUSIVE_INCLUSIVE, что означает, что любой текст, добавленный до 1, не включен в область стиля, но любой текст, добавляемый после 1 и после или до 2, всегда включается в режим жирного шрифта, поэтому только жирный шрифт "12x3".

    int end=3;
    spanFlag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE; 
    foregroundSpan = new ForegroundColorSpan(Color.RED);
    spannableString.setSpan(foregroundSpan, start, end, spanFlag);
    txv.setText(spannableString);

Это вызовет еще один независимый красный стиль для текста "x1", но, поскольку уже другой красный стиль применяется к тексту "x12x3", мы не увидим никакой разницы в txv. Чтобы на самом деле изменить ранее примененный красный стиль, нам нужно передать тот же объект ForegroundColorSpan, который мы делали, когда мы вызывали метод setSpan в первый раз, мы должны использовать следующий код вместо приведенного выше:

    int end=3;
    spanFlag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE; 
    spannableString.setSpan(ob, start, end, spanFlag); //ob refers to the same the styling object as we specified on the first occasion
    txv.setText(spannableString);

Это приведет к тому, что только "x1" будет красным, а также, если мы добавим какой-либо текст после "1" или перед "x", то этот текст не будет включен в красную область стиля, но любой текст после "x" и до " 1 "всегда включен в красную область стилей из-за флага SPAN_EXCLUSIVE_EXCLUSIVE, который мы указали на этот раз.

9.Последнее, если мы хотим полностью удалить стиль и его флаг-флаг span, то мы можем вызвать метод removeSpan (Object what), определенный интерфейсом Spannable, реализованным классом SpannableStringBuilder, нам нужно передать тот же объект стиля в метод removeSpan как мы дали методу setSpan.

Благодаря приведенным выше ответам, особенно пример цвета помог мне понять эти флаги правильно.