4

What I'm trying to do is to assign a different color to every other row in a RecycledView. I created a custom RecycledView.Adapter, and in onCreateViewHolder method I have this:

// Create a row_folder view
View view = inflater.inflate(R.layout.row_folder, parent, false);

if(position % 2 == 0) {
   view.setBackgroundColor(Color.BLACK);
}


// Use MyViewHolder to bind the view
MyViewHolder holder = new MyViewHolder(view);

return holder;

The color does not get assigned. What am I missing ? Thanks.

edited: row_folder xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="72dp"
        android:background="@color/my_white"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/folder_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:src="@drawable/folder_icon" />

        <TextView
            android:id="@+id/folder_name"
            android:layout_width="190dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:text="The Mills"
            android:textColor="@color/my_blue"
            android:textSize="16sp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/folder_content_icon"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_gravity="center"
            android:layout_marginLeft="12dp"
            android:src="@drawable/folder_content_icon" />

        <TextView
            android:id="@+id/content_number"
            android:layout_width="30dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:gravity="left"
            android:text="3"
            android:textColor="@color/my_blue"
            android:textSize="16sp"
            android:textStyle="bold" />
    </LinearLayout>

</LinearLayout>
Nactus
  • 702
  • 2
  • 13
  • 35
  • Thanks for your comment. I'm not sure where getView goes in this context. Can it be implemented in the custom adapter ? Can you give me an example? Thanks. – Nactus Feb 26 '15 at 11:06
  • getView is a method of Adapter. Even if you're using custom Adapter, it will be there. Beside, it is the method where you actually inject data in the view. Btw, are you able to solve it? – Tushar Gogna Feb 26 '15 at 11:27
  • @Tushar, after looking at this: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html I'm afraid the getView option won't work. It seems like RecyclerView.Adapter does not have a getView method. Any other suggestions ? – Nactus Feb 26 '15 at 11:29
  • It has `getItemViewType` instead. Add that if condition in it. – Tushar Gogna Feb 26 '15 at 11:36
  • Ok, so I implemented the getItemViewType instead, this method seems to get called for every row, but since it only takes a parameter of type int position, how do I reference the view I want to change the color for ? – Nactus Feb 26 '15 at 11:52
  • Kinda like [this](http://stackoverflow.com/a/26245463/3531756) or even better way of doing is in **onBindViewHolder**. – Tushar Gogna Feb 26 '15 at 11:56
  • Yah, using the onBindViewHolder(MyViewHolder holder, int position) was my initial thought, but I can't seem to be able to either extract (from the holder) or target the current view to access the "setBackgroundColor()" method – Nactus Feb 26 '15 at 12:08
  • But it should work, show your code. – Tushar Gogna Feb 26 '15 at 12:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71774/discussion-between-tushar-and-nactus). – Tushar Gogna Feb 26 '15 at 12:29

2 Answers2

11

do something like this in your recycler view adapter:

@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
     if(position % 2 == 0) 
     {
         //holder.rootView.setBackgroundColor(Color.BLACK);
         holder.rootView.setBackgroundResource(R.color.black);
     }
     else 
     {
         //holder.rootView.setBackgroundColor(Color.WHITE);
         holder.rootView.setBackgroundResource(R.color.white);
     }
}

EDIT:

Change your xml file like this: row_folder.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="72dp"
    android:background="@color/my_white"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/folder_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:layout_marginLeft="16dp"
        android:src="@drawable/folder_icon" />

    <TextView
        android:id="@+id/folder_name"
        android:layout_width="190dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="16dp"
        android:text="The Mills"
        android:textColor="@color/my_blue"
        android:textSize="16sp"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/folder_content_icon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center"
        android:layout_marginLeft="12dp"
        android:src="@drawable/folder_content_icon" />

    <TextView
        android:id="@+id/content_number"
        android:layout_width="30dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="16dp"
        android:gravity="left"
        android:text="3"
        android:textColor="@color/my_blue"
        android:textSize="16sp"
        android:textStyle="bold" />
</LinearLayout>

create one more variable in your ViewHolder class as below:

public static class ViewHolder extends RecyclerView.ViewHolder
{
    LinearLayout rootView;//newly added field
    public ViewHolder(View view)
    {
        super(view);
        rootView=(LinearLayout)view.findViewById(R.id.rootView);
    }
}

I hope it might work.

Amrut Bidri
  • 6,276
  • 6
  • 38
  • 80
  • thanks for your answer. The problem I'm having is with this part: "holder.rootView". Where does the rootView get assigned to the holder, in your example ? – Nactus Feb 26 '15 at 12:38
  • it is the root view of your R.layout.row_folder, it may be Linearlayout or RelativeLayout. Post this XML for exact answer. – Amrut Bidri Feb 26 '15 at 12:40
  • thanks for your answer. I made it work, it was the "backgroundColor" xml property on my row_folder second linear layout that was blocking all the further color dynamic assignation. I removed that line and then I was able to implement it based on your first example. It also worked from the "onCreateViewHolder" by using a counter variable to keep track of the current row (just for testing). Please edit your answer moving it back before the edit and also add the xml backgroundColor property to be able to mark this answer as "accepted". Thanks – Nactus Feb 26 '15 at 13:25
  • 1
    Also, in regards to my previous statement, this is also important to note: "Every view holder used by the RecyclerView has to subclass RecyclerView.ViewHolder and this class has a public field called itemView which contains the View associated with the ViewHolder." The rootView part is not necessary as holder.itemView works fine. (Taken from here: http://stackoverflow.com/questions/27206593/recyclerview-how-can-i-get-a-reference-to-each-rows-view) – Nactus Feb 26 '15 at 15:21
0

I'm putting this here just for future reference for those trying to apply a zebra striping like color effect on RecyclerView's row which basically holds a CardView.

XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
>

  <!--Content goes here-->


</android.support.v7.widget.CardView>

Now, in adapter side, initialize the CardView first (I'm using butterknife binding).

public class YooViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.cv)
        CardView cardView;

        public YooViewHolder(View v) {
            super(v);
            ButterKnife.bind(this, v);

        }
}

And finally at onBindViewHolder, place this single line of code.

holder.cardView.setCardBackgroundColor(
  ContextCompat.getColor(mContext, 
    position % 2 == 0 ? R.color.white : R.color.white_grayish));

Be sure to use setCardBackgroundColor (and not setBackgroundColor) on CardView.

fluffyBatman
  • 6,524
  • 3
  • 24
  • 25