Динамическая установка цвета фона recyclerview/cardview

Мне интересно, можно ли изменить цвет фона каждого элемента представления ресайклера, если элемент содержит определенное слово. Например, мой пользовательский элемент содержит 4 текстовых представления и 1 флажок, я хочу, чтобы цвет фона был светло-коричневым, если элемент содержит слово «мертвый», красный, если он содержит «скамейка».. т. д. т. д.. есть ли способ сделай это?

Вот мой item.xml:

<android.support.v7.widget.CardView
android:id="@+id/card_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp" >


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="Squat"
    android:textSize="20sp"
    android:paddingStart="5dp"
    android:paddingLeft="5dp"
    android:paddingRight="50dp"
    android:id="@+id/txtExercise"

    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="%"
    android:textSize="20sp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:id="@+id/txtPercentage"
    android:layout_centerVertical="true"
    android:layout_toLeftOf="@+id/txtReps"
    android:layout_toStartOf="@+id/txtReps"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="Reps"
    android:paddingRight="10dp"
    android:paddingLeft="10dp"
    android:textSize="20sp"
    android:id="@+id/txtReps"
    android:layout_alignTop="@+id/check1"
    android:layout_toLeftOf="@+id/txtWeight"
    android:layout_toStartOf="@+id/txtWeight"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Weight"
    android:paddingRight="10dp"
    android:paddingLeft="20dp"
    android:textSize="20sp"
    android:id="@+id/txtWeight"
    android:layout_alignParentTop="true"
    android:layout_toLeftOf="@+id/check1"
    android:layout_toStartOf="@+id/check1"/>

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/check1"
    android:paddingRight="10dp"
    android:checked="false"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"/>

</RelativeLayout>

And my recycler view:

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {

Context mContext;
ArrayList<Workout> workout;
SharedPreferences prefs;
int firstSecondOrThird;


public MyRecyclerAdapter(Context context, ArrayList<Workout> workout, int thePosition) {
    mContext = context;
    this.workout = workout;
    this.firstSecondOrThird = thePosition;
}
// INITIALIZE HOLDER
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_item, null);
    MyViewHolder holder = new MyViewHolder(view);

    return holder;
}

//BIND DATA TO VIEWS
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
    holder.exercise.setText(workout.get(position).getExercise());
    holder.percent.setText(workout.get(position).getPercent());
    holder.reps.setText(workout.get(position).getReps());
    holder.weight.setText(workout.get(position).getWeight());
    holder.check1.setOnCheckedChangeListener(null);
    final Workout isCheck = workout.get(position);
    holder.check1.setChecked(isCheck.isCheck1());
    prefs = mContext.getSharedPreferences("checkstate", Context.MODE_PRIVATE);
    holder.check1.setChecked(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false));
    isCheck.setCheck1(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false));

    holder.check1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            isCheck.setCheck1(isChecked);
            prefs.edit().putBoolean(firstSecondOrThird+"checkState"+position, isChecked).apply();
        }
    });

}

@Override
public int getItemCount() {
    return workout.size();
}
}

Спасибо!




Ответы (2)


В базовом классе ViewHolder itemView общедоступен, поэтому в методе onBindViewHolder() вы проверяете, какой цвет вам нужен, и устанавливаете его.

    int colorResId = R.color.default;
    if (workout.get(position).getExercise().contains("bench") {
        colorResId = R.color.red;
    //  more tests for which color to use
    }
    int color = getResources.getColor(colorResId, context);
    ((CardView) holder.itemView).setCardBackgroundColor(color);
person kris larson    schedule 08.08.2016
comment
Чтобы добавить к этому, вы можете добавить еще одно поле в свой класс Workout. Что-то вроде int workOutColor создайте геттер и сеттер, а затем в коде вы можете просто сделать holder.itemView.setBackgroundResource(workout.get(position).getWorkOutColor()); Это намного чище и заставляет ваш класс выполнять логику. - person Gary Holiday; 08.08.2016
comment
Спасибо, это работает хорошо, к сожалению, когда я его использую, он в основном избавляется от атрибутов просмотра карт, углы больше не изогнуты и т. Д. Есть ли способ обойти это? - person LBJ33; 08.08.2016
comment
Также кажется, что цвета продолжают меняться, лол ... иногда я запускаю приложение, и оно работает правильно ... в других случаях оно меняет цвета на цвета, которых нет нигде в моем приложении? - person LBJ33; 08.08.2016
comment
О да, есть ошибка с цветовыми ресурсами, я обновил свой ответ, чтобы показать вам, как ее обойти. - person kris larson; 08.08.2016
comment
getResources не работает, пишет, что не может быть разрешено - person LBJ33; 09.08.2016
comment
исправлено путем изменения getResources на ContextCompat.getColor - person LBJ33; 09.08.2016
comment
Это сработало для того, чтобы цвета взаимодействовали, но все же срезает углы с просмотра карт :( - person LBJ33; 09.08.2016
comment
Обновленный ответ, посмотрите, поможет ли это углам. - person kris larson; 09.08.2016
comment
Это сработало! Спасибо!! Просто пришлось также вынуть новую часть ColorDrawable: ((CardView)holder.itemView).setCardBackgroundColor(color); - person LBJ33; 09.08.2016
comment
что, если я хочу изменить цвет фона за пределами средства просмотра, т.е. цвет самого recyclerview, но динамический для каждого элемента - person Siddarth G; 19.11.2017
comment
@SiddarthG Вызовите setBackgroundColor на RecyclerView, чтобы изменить общий цвет. Если вы хотите изменить цвет элемента, измените свойство, которое повлияет на цвет фона вашего элемента, а затем вызовите notifyDataSetChanged. В onBindViewHolder проверьте свойство и измените цвет фона. Если это неясно, опубликуйте новый вопрос с соответствующим кодом для всего сообщества. - person kris larson; 20.11.2017

Таким образом, ваш ViewHolder имеет связанный с ним View. Который раздувается с помощью xml-файла, который вы разместили. Теперь в вашем методе onBindViewHolder вы привязываете свои данные к вашему MyViewHolder. Вы можете получить View из MyViewHolder, вызвав holder.itemView, который возвращает объект View.

View itemView = holder.itemView;

Теперь отсюда вы можете получить ссылки на свои TextView, Button и т. д., позвонив findViewById на itemView.

Так, например, если у вас есть TextView в вашем XML-файле с идентификатором android:id="@+id\myTextView, вы можете сделать следующее в своем onBindViewHolder,

public void onBindViewHolder(MyViewHolder holder, final int position) {
    //..... Other stuff
    View itemView = holder.itemView;
    TextView myTextView = (TextView) itemView.findViewById(R.id.myTextView);
    myTextView.setBackgroundResource(context.getResources().getColor(android.R.color.holo_red_dark));
   //...... Other stuff
}
person wanpanman    schedule 08.08.2016
comment
Я пытаюсь решить проблему в RecyclerView и наткнулся на ваш ответ выше. Буду признателен за любые мысли или идеи по этому вопросу: stackoverflow.com/questions/44739404/ - person AJW; 25.06.2017