Фон Android View неожиданно меняется

Я создаю приложение с большим количеством экранов. на большинстве экранов есть вид сверху с цветом фона.

Я часто меняю этот цвет, используя view.setBackgroundColor(цвет)

Вот что странно: иногда после установки цвета одного вида, скажем, # f14fb7, при навигации в приложении фоны других представлений устанавливаются на этот цвет, если я не хочу их. Иногда бывает даже с представлениями, для которых я не задавал идентификатор, поэтому в этих представлениях не было вызвано setBackgroundColor.

Это случается редко и не соответствует ни одному потоку, который я пробовал.

Когда я убиваю приложение и перезапускаю его, все работает так, как должно.

Мое единственное предположение - это некоторая ошибка утечки памяти, но я надеюсь, что есть более простое объяснение.

Может кто-нибудь подумать о какой-то причине для этого?

* Это происходит на моей Галактике S3.

Ответы

Ответ 1

Без кода это нелегко... но я думаю, вы повторно используете один и тот же ColorDrawable для нескольких видов, и если вы посмотрите на исходный код View.setBackgroundColor():

public void setBackgroundColor(int color) {
    if (mBGDrawable instanceof ColorDrawable) {
        ((ColorDrawable) mBGDrawable).setColor(color);
    } else {
        setBackgroundDrawable(new ColorDrawable(color));
    }
}

Вы можете видеть, что он меняет цвет ColorDrawable и не создает новый каждый раз. Я уверен, что именно поэтому у вас такое странное поведение.

ИЗМЕНИТЬ

Когда вы устанавливаете исходный цвет фона в xml с помощью android:background, вы делаете это (в соответствии с android doc):

Установите фон для заданного ресурса. Ресурс должен ссылаться на объект Drawable

По моему мнению, он установит поле View.mBGDrawable во время раздувания. Я предлагаю вам использовать View.setBackgoundDrawable(new ColorDrawable(the_color_int_code))) вместо setBackgroung(the_color_int_code). Он должен решить вашу проблему.

Ответ 2

Это обычно происходит, если у вас есть представление, цвет которого установлен в xml ex:

android:background="@color/cyan" 

Теперь это внутренне создает новый ColorDrawable - позволяет называть его conceptual_drawable_cyan внутри этого класса вида. Теперь, когда один и тот же вид назначается другим цветом программно, используя:

view.setBackgroundColor(newColor);

Внутри этого представления вместо создания другого drawable он устанавливает этот newColor в drawable_cyan. Следовательно, с этого момента, если вы где-нибудь используете

android:background="@color/cyan" 

представление фактически использует conceptual_drawable_cyan с newColor.

Решение:

Вместо использования setBackgroundColor для программного программирования цвета используйте:

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        view.setBackground(new ColorDrawable(newColor));
    } else {
        view.setBackgroundDrawable(new ColorDrawable(newColor));
    }

Ответ 3

Создайте файл colors.xml в папке "values". Пример:

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="pink">#f14fb7</color></resources>

Используйте view.setBackgroundResource(R.color.pink);