Как объединить некоторые составные объекты?

Я делю составной объект на 3 части, делаю разные операции, а потом мне нужно их объединить.

Spannable str = editText.getText();
Spannable selectionSpannable = new SpannableStringBuilder(str, selectionStart, selectionEnd);
Spannable endOfModifiedSpannable = new SpannableStringBuilder(str, selectionEnd, editText.getText().length());
Spannable beginningOfModifiedSpannable = new SpannableStringBuilder(str, 0, selectionStart);            

Как мне это сделать? Я не нашел требуемый метод или конструктор для этого.


person Eugene    schedule 05.01.2011    source источник


Ответы (5)


Вы можете использовать это:

TextUtils.concat(span1, span2);

http://developer.android.com/reference/android/text/TextUtils.html#concat(java.lang.CharSequence...)

person xil3    schedule 05.01.2011
comment
Иногда, не очень часто, Java упрощает задачу. Я люблю те времена. +1 - person Madbreaks; 31.10.2012
comment
@Madbreaks это связано не с Java, а с Android API. Это можно было бы упростить и на C++. - person Display Name; 16.07.2014
comment
В моем случае у этого метода были некоторые проблемы: TextUtils.concat(span1, " ", span2); стиль (т.е. span) для span1 исчез, осталось только его строковое представление. Обертывание в Spanned не помогло. - person marwinXXII; 01.08.2014
comment
То же самое здесь: первый spannable теряет стиль, только второй сохраняет свой стиль! - person Muhammad Alfaifi; 27.10.2014
comment
Если ваш первый стиль промежутка исчез, это может быть связано с тем, что вы использовали один и тот же StyleSpan на обоих промежутках. Вам нужно создать новый StyleSpan для каждого диапазона. (см. этот ответ) - person minipif; 06.07.2015
comment
@marwinXXII " " - это String, который работает с интерфейсом CharSequence, но не Spannable. new SpannableString(" ") будет работать вместо " " - person HaydenKai; 17.07.2016
comment
@marwinXXII Я нашел обходной путь для этого в своем ответе: stackoverflow.com/a/49080221/5054192 - person nulldev; 03.03.2018

Спасибо, это работает. Я заметил, что могу объединить даже 3 составных объекта:

(Spanned) TextUtils.concat(foo, bar, baz)
person Eugene    schedule 05.01.2011
comment
Если вы посмотрите на сигнатуру метода, она принимает CharSequence... что означает, что она объединит столько, сколько вы ей дадите. - person Ljdawson; 22.05.2012
comment
Работает просто отлично! Спасибо! - person sud007; 25.06.2020

Я знаю, что это старо. Но после небольшого изменения kotlin stdlib у меня есть этот код:

fun <T> Iterable<T>.joinToSpannedString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): SpannedString {
    return joinTo(SpannableStringBuilder(), separator, prefix, postfix, limit, truncated, transform)
            .let { SpannedString(it) }
}

Надеюсь, это может помочь кому-то.

person AlexKost    schedule 03.11.2017

Используйте 1_.

Еще лучше — сделайте перегрузку оператора kotlin:

operator fun Spannable.plus(other: Spannable): Spannable{
    return SpannableStringBuilder(this).append(other)
}

просто добавьте это в любой файл kotlin в качестве функции верхнего уровня.

и вы можете объединить с помощью +:

val spanA = ...
val spanB = ...

val concatenatedSpan = spanA + spanB
person Mardann    schedule 10.01.2021

Как сказал marwinXXII в комментарии, использование TextUtils.concat действительно работает, но может привести к потере стилей в некоторых случаях, когда у вас есть несколько экземпляров одного и того же диапазона в одном CharSequence.

Обходной путь может состоять в том, чтобы записать CharSequence в Parcel, а затем прочитать его обратно. Пример кода расширения Kotlin для этого ниже:

fun CharSequence.cloneWithSpans(): CharSequence {
    val parcel = Parcel.obtain()
    TextUtils.writeToParcel(this, parcel, 0)
    parcel.setDataPosition(0)
    val out = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel)
    parcel.recycle()
    return out
}

Пример использования этого кода:

TextUtils.concat(*yourListOfText.map { it.cloneWithSpans() }.toTypedArray())

Теперь вы можете объединять множество CharSequences, не беспокоясь о потере каких-либо стилей и форматирования, которые у вас есть!

Обратите внимание, что это будет работать для большинства стилей, но не всегда, но этого должно быть достаточно, чтобы охватить все основные стили.

person nulldev    schedule 03.03.2018