2013-11-19 3 views
2

Я пытаюсь сделать игру, чтобы помочь детям научиться математике. Я код цвета, чтобы они могли следовать логике. Я также использую textView.append() для создания длинной строки для ввода в действие.SpannableString изменяет цвет в первый раз, но не при повторном использовании

Поскольку я повторно использую те же цифры/символы в инструкции, мне нужен способ легко перерабатывать SpannableStrings, но кажется, что изменения, которые я делаю, применяются правильно в первый раз, но иногда иногда работают, иногда частично работают (например, правильный размер/выравнивание, но неправильный цвет) или вообще не работают. Я получаю все это. Кажется, я не вижу, чтобы кто-то испытывал подобную проблему в Stackoverflow или где-либо еще в Google.

Вот мой код (упрощенно):

// Declare static variables 
    public static Spannable PLUS = new SpannableString("+ "); 
    public static Spannable MINUS = new SpannableString("- "); 
    public static Spannable TIMES = new SpannableString("X "); 
    public static Spannable DIVIDED_BY = new SpannableString("/ "); 
    public static Spannable EQUALS = new SpannableString("= "); 

    // Function to color these strings. 
    public void colorStrings() { 
    makeBlack(PLUS); 
    makeBlack(MINUS); 
    makeBlack(TIMES); 
    makeBlack(DIVIDED_BY); 
    makeBlack(EQUALS); 
    makeBlack(QMARK); 
    } 

    // Function that actually sets color, size, and alignment. 
    public Spannable makeBlack(Spannable s) {s.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.color_black)), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
    s.setSpan(new AbsoluteSizeSpan((int) getResources().getDimension(R.dimen.big_text)), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
    s.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
    return s; 
    } 

    // Implementing above code by setting math1 TextView to give it colors. 
    // Note that this is the exact code used for the first colored string in the 
    // screen capture below. 
    math1.setText(XX); 
    math1.append(PLUS); 
    math1.append(YY); 
    math1.append(PLUS); 
    math1.append(ZZ); 
    math1.append(EQUALS); 
    math1.append(QMARK); 

(Обратите внимание, что я не предоставил код XX, YY или ZZ ... это немного сложнее, так как я должен получить данные из параметра sharedpreference, но они по существу та же проблема, что и другие математические символы/операторы).

Это в результате захвата экрана:

enter image description here

Пожалуй, лучшим примером моей проблемы является + (знак плюс). Сначала он черный, как ожидалось, но только 4 символа позже (включая пробелы) - это неправильный цвет (синий, который он, скорее всего, получил из предыдущей SpannableString), хотя правильно выровнен и правильно. В следующей цветной строке он отображается как ожидалось (черный, по центру, большой), но после этого он не отформатирован вообще в последующих «цветных» строках (малый, выравниваемый по левому краю, зеленый, как текст абзаца). Используемый код выглядит точно так же, как указано выше (т. Е. Math1.append (PLUS);), но результат не всегда соответствует ожидаемому.

Последняя информация: перед глобальным объявлением моих переменных я локально объявлял их каждый раз, используя те же функции makeBlack() и math1.append(), и работал отлично. Я получаю это странное поведение после глобальной настройки моих переменных.

Какие-либо предложения о том, что здесь происходит неправильно?

ответ

6

Вы не можете повторно использовать один и тот же диапазон несколько раз. Даже если диапазон точно такой же, вам нужно создать уникальный диапазон для каждого раздела строки, которую вы хотите изменить.

Я не уверен, где я это прочитал, но могу подтвердить ответ.

Создайте уникальный диапазон для каждой вещи, которую вы хотели бы изменить.

+0

Отметить это как правильный ответ из-за чата, который у нас был на G +. Я заметил, что я получил код для работы при настройке цвета каждый раз, когда я использовал строку, например. "makeBlack (PLUS); math1.append (PLUS);". Это позволило мне повторно использовать Spannable, который я объявлял глобально, но каждый отдельный интервал (установленный makeBlack();) должен быть сброшен каждый раз. Спасибо за помощь! – aikorei

1

Объекты Span не должны использоваться повторно. Раньше у меня была аналогичная проблема.

+0

Я не видел этого в документации разработчика ... я что-то пропустил? – aikorei

+0

Я ничего не видел об этом в документации. Разве этот ответ не должен быть отмечен как правильный ответ? Он говорит то же самое, но гораздо более кратким и первым! –

4

подмигнули Возможное использование тот же период несколько раз, используя

CharacterStyle.wrap(CharacterStyle c) 

каждый раз, когда вам нужно использовать один и тот же диапазон, Пазинг его в качестве параметра.

3

Просто хочу перезвонить, так как я столкнулся с этой же проблемой. Если вы погружаетесь в класс Spannable, например SpannableStringBuilder, становится понятно, почему вы не можете повторно использовать Span.Когда вы устанавливаете промежуток, этот блок выполняется:

for (int i = 0; i < count; i++) { 
    if (spans[i] == what) { 
     int ostart = mSpanStarts[i]; 
     int oend = mSpanEnds[i]; 

     if (ostart > mGapStart) 
      ostart -= mGapLength; 
     if (oend > mGapStart) 
      oend -= mGapLength; 

     mSpanStarts[i] = start; 
     mSpanEnds[i] = end; 
     mSpanFlags[i] = flags; 

     if (send) sendSpanChanged(what, ostart, oend, nstart, nend); 

     return; 
    } 
} 

В основном этот код перебирает существующие пролеты, сравнивает продолжительность быть установлена, и если он совпадает затем обновляет пролетную границу. Единственный способ предотвратить то, что if (spans[i] == what) является истинным, передается в новом экземпляре вашего диапазона.