Reputation: 1874
i am trying to write a RecyclerView with CardViews and using CAB trying to delete multiple Cards on selection .How do i give background color to the selected cards. i am trying to use statelistdrawable as the following :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="@color/primary_dark" />
<item android:drawable="@android:color/transparent" />
</selector>
and apply it to the CardView layout as :
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/statelist_item_background"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/imageView"
android:tag="image_tag"
android:layout_width="72dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:src="@drawable/one"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_weight="2"
android:orientation="vertical"
>
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView
android:id="@+id/textViewEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
below is the code for my adapter
public class modeladapter extends RecyclerView.Adapter<modeladapter.myholder> {
ArrayList<MyModel> arraylist;
SparseBooleanArray selecteditems;
public modeladapter(ArrayList<MyModel> ar) {
arraylist=ar;
selecteditems=new SparseBooleanArray();
}
public void removeData(int position) {
arraylist.remove(position);
notifyItemRemoved(position);
}
public MyModel getItem(int position) {
return arraylist.get(position);
}
public void addData(MyModel newModelData, int position) {
arraylist.add(position, newModelData);
notifyItemInserted(position);
}
public void toggleSelection(int pos) {
if (selecteditems.get(pos, false)) {
selecteditems.delete(pos);
}
else {
selecteditems.put(pos, true);
}
notifyItemChanged(pos);
}
public void clearSelections() {
selecteditems.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selecteditems.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<Integer>(selecteditems.size());
for (int i = 0; i < selecteditems.size(); i++) {
items.add(selecteditems.keyAt(i));
}
return items;
}
@Override
public modeladapter.myholder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater lf=LayoutInflater.from(viewGroup.getContext());
View v = lf.inflate(R.layout.card_lay, viewGroup, false);
// v.setOnClickListener(Activity_Main.listener);
myholder m=new myholder(v);
return m;
}
@Override
public void onBindViewHolder(modeladapter.myholder m, int i) {
m.cimage.setImageResource(arraylist.get(i).url);
m.email.setText(arraylist.get(i).email);
m.name.setText(arraylist.get(i).name);
m.itemView.setActivated(selecteditems.get(i,false));
}
@Override
public int getItemCount() {return (arraylist.size());}
public static class myholder extends RecyclerView.ViewHolder
{
ImageView cimage;
TextView name,email;
public myholder(View itemView) {
super(itemView);
cimage= (ImageView) itemView.findViewById(R.id.imageView);
name= (TextView) itemView.findViewById(R.id.textViewName);
email= (TextView) itemView.findViewById(R.id.textViewEmail);
if(itemView.isActivated())
itemView.setBackgroundColor(itemView.getContext().getResources().getColor(R.color.primary_dark));
else
itemView.setBackgroundColor(Color.parseColor("#ffffff"));
}
}
kindly update how i can change the background color of selected items. thanks
Upvotes: 5
Views: 20156
Reputation: 116402
There are various ways to do it. Here's how to do it programmatically:
Use your own custom card view:
class SelectableCardView : MaterialCardView {
@ColorInt
private var unselectedBackgroundColor = 0
@ColorInt
private var selectedBackgroundColor = 0
constructor(context: Context?) : super(context) {
unselectedBackgroundColor = cardBackgroundColor.defaultColor
setCardBackgroundColor(ColorStateList(arrayOf(intArrayOf(android.R.attr.state_selected), IntArray(0)), intArrayOf(selectedBackgroundColor, unselectedBackgroundColor)))
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
unselectedBackgroundColor = cardBackgroundColor.defaultColor
setCardBackgroundColor(ColorStateList(arrayOf(intArrayOf(android.R.attr.state_selected), IntArray(0)), intArrayOf(selectedBackgroundColor, unselectedBackgroundColor)))
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
unselectedBackgroundColor = cardBackgroundColor.defaultColor
setCardBackgroundColor(ColorStateList(arrayOf(intArrayOf(android.R.attr.state_selected), IntArray(0)), intArrayOf(selectedBackgroundColor, unselectedBackgroundColor)))
}
init {
selectedBackgroundColor = ContextCompat.getColor(context, R.color....)
}
}
Or when inflating, set the color yourself from outside:
val cardView = result!!.cardView
val selectedBackgroundColor = ContextCompat.getColor(inflater.context, R.color....)
val unselectedBackgroundColor = cardView .cardBackgroundColor.defaultColor
cardView.setCardBackgroundColor(ColorStateList(arrayOf(intArrayOf(android.R.attr.state_selected), IntArray(0)),intArrayOf(selectedBackgroundColor, unselectedBackgroundColor)))
Of course, you could set the card background color set via XML, but then you would have to have the default one also being set. I don't recommend it because it might change in the future, as it was recently.
For example, in the past is was cardview_dark_background
and changed to design_dark_default_color_background
on dark theme, and was cardview_light_background
and changed to design_default_color_background
on normal theme.
Upvotes: 0
Reputation: 157
Instead of changing the CardView background color, change the LinearLayout inside the CardView:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/statelist_item_background">
<ImageView
android:id="@+id/imageView"
android:tag="image_tag"
android:layout_width="72dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:src="@drawable/one"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_weight="2"
android:orientation="vertical"
>
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView
android:id="@+id/textViewEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Medium Text"
android:textAppearance="?
android:attr/textAppearanceMedium"/>
</LinearLayout>
</LinearLayout>
Upvotes: 0
Reputation: 1229
card_view:cardBackgroundColor="@color/statelist_item_background"
Upvotes: 0
Reputation: 2109
For anyone new to this issues, it's worth noting as of support library v24, the CardView now supports a ColorStateList. (Note: this is a color state list, not a drawable state list)
Here's the link: https://code.google.com/p/android/issues/detail?id=78198
Upvotes: 2
Reputation: 55527
You do not necessarily need to have a StateListDrawable
You need to have a method in your adapter that checks for selections:
sparseArray.valueAt(i).isSelected()
Then in your RecylcerView.Adapter
, change:
if (itemView.isActivated())
itemView.setBackgroundColor(itemView.getContext().getResources().getColor(R.color.primary_dark));
else
itemView.setBackgroundColor(Color.parseColor("#ffffff"));
To(You need to change the cardView, not the itemView):
viewHolder.cardView.setCardBackgroundColor(sparseArray.valueAt(i).isSelected() ? Color.LTGRAY : Color.WHITE);
Upvotes: 9