Динамический оттенок, который можно рисовать в адаптере, меняет цвет для всех

Я получаю массив строк с моего сервера, используя залповое соединение. Каждая отдельная строка содержит другой цвет в шестнадцатеричном формате. Я использую этот цвет, чтобы установить оттенок в адаптере.

Вот мой код в адаптере:

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
    // Get item from position
    MyObject object = array_data.get(position);
    ...
    ...
    Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_beenhere_black_24dp);
    Drawable wrappedDrawable;
    if (unwrappedDrawable != null) {
        wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
        DrawableCompat.setTint(wrappedDrawable, object.getMyColor());
        holder.imvPreparationTime.setImageDrawable(wrappedDrawable);
    }

К сожалению, поведение некорректно. Все элементы, которые можно рисовать в recyclerview, имеют один и тот же цвет вместе, и он меняется для всех во время прокрутки.

введите здесь описание изображения

Как я могу выполнить свою цель? Я хочу, чтобы каждый предмет имел свой цвет и не менялся.


person F.M.    schedule 22.10.2019    source источник
comment
Этот пост содержит ответ: https://stackoverflow.com/questions/31944501/changing-color-of-single-drawable-in-recyclerview-will-change-all-drawables   -  person F.M.    schedule 24.10.2019


Ответы (2)


Это можно сделать с помощью Drawable.mutate() . В вашем классе адаптера в блоке onBindViewHolder(..) используйте приведенный ниже фрагмент кода, чтобы изменить цвет оттенка вашего рисунка -

for (Drawable drawable : myTextView.getCompoundDrawablesRelative()) {
                    if (drawable != null) {
                        Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
                        Drawable mutableDrawable = wrappedDrawable.mutate();
                        DrawableCompat.setTint(mutableDrawable, ContextCompat.getColor(context, R.color.desiredColor));
                    }
                }

Примечание. Этот фрагмент кода я использовал для изменения оттенка отображаемого текста. Итак, если вам нужно изменить оттенок изображения или файла для рисования, просто сделайте это так:

Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
                        Drawable mutableDrawable = wrappedDrawable.mutate();
                        DrawableCompat.setTint(mutableDrawable, ContextCompat.getColor(context, R.color.colorGrayD5));

Удачного кодирования!

person Abhijeet    schedule 06.08.2020
comment
У меня была эта проблема, и ваше решение сработало! - person Sargius; 19.07.2021

Поскольку recyclerView повторно использует элементы, часто происходит такое поведение. Самый простой способ - поставить if else для вида, для которого вы хотите установить оттенок. Например.

if (unwrappedDrawable != null) {
        wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
        DrawableCompat.setTint(wrappedDrawable, object.getMyColor());
        holder.imvPreparationTime.setImageDrawable(wrappedDrawable);
    } else {
        holder.imvPreparationTime.setImageDrawable(<Some Other drawable, for example default one>);
    }

Идея состоит в том, чтобы заставить recycler view рисовать что-то на элементе, а не повторно использовать уже установленный.

person Oleksandr Martynets    schedule 22.10.2019
comment
Я пробую этот код, но поведение такое же, как и у предыдущего. Почему вы говорите мне установить else для «if (unwrappedDrawable! = null)»? Это условие уже выполняется, потому что «из Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_beenhere_black_24dp);» линия. - person F.M.; 24.10.2019