Quantcast
Channel: Sameh Attia
Viewing all articles
Browse latest Browse all 1406

How to use RecyclerView and CardView on Android Lollipop

$
0
0
http://xmodulo.com/recyclerview-cardview-android.html

Android Lollipop introduced a whole new design paradigm, called Material Design. It encourages the use of bolder colors, flatter UI elements, and smoother animations. Android Lollipop introduces corresponding new APIs to help developers implement the Material Design guidelines, and two of these UI widgets are RecyclerView and CardView. The RecyclerView is designed to replace the ListView, while the CardView is a new type of layout.
This article shows how powerful and easy to use these two widgets can be together.

Setup

Both RecyclerView and CardView are new API's, added in SDK 21. Thankfully, they have been made available through the support libraries. This means that both widgets are available for devices running API Level 7 (Gingerbread) and above.
For both RecyclerView and CardView to be available in an Android project, they have to be added to the dependency list. In AndroidStudio, they can both be added by:
  • Right click on the project name
  • Select "Open Module Settings"
  • Select "Dependencies"
  • Add both cardview and recyclerview

RecycleView

RecyclerView was designed to replace the ListView, and it does this very well. ListView can be implemented in a variety of ways, although Google encouraged developers to use the ViewHolder design pattern to achieve smoother scrolling (remember project butter?). The ViewHolder pattern achieves this smoother scrolling by keeping list items in memory, so that they can be accessed as needed, rather being repeatedly looked up. RecyclerView forces the use of the ViewHolder pattern, which is a good thing.
The RecyclerView is used just like the ListView. You add the RecyclerView to the Layout Manager exactly where a ListView should be in our Activity layout file (activity_main.xml),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp"
    tools:context=".MainActivity">
 
    
        android:id="@+id/recyclerList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
That's it. We now have a RecyclerView in our code. We will explore how to make use of it later in the tutorial. For now, that's all that's needed.

CardView

The CardView widget displays information inside cards. Each card will represent a row in the RecyclerView. Internally, CardView is a subclass of FrameLayout, so it is not a stretch to treat your CardView as you would a FrameLayout. We create a layout file called card_view.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    card_view:cardCornerRadius="4dp"
    android:layout_margin="5dp">
 
    
        android:id="@+id/cardBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:gravity="center_vertical"
            android:textColor="@android:color/white"
            android:textSize="30dp"/>
 
        
            android:id="@+id/hexValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Content"
            android:gravity="center_vertical"
            android:textColor="@android:color/white"
            android:textSize="25dp"
            android:layout_below="@+id/name"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="5dp"/>
 
    
 
In the code above, note 'xmlns:card_view="http://schemas.android.com/apk/res-auto"' and 'card_view:cardCornerRadius="4dp"'. While CardView is a FrameLayout, it has its own extensions that provide easy and powerful customisations.

Putting Them Together

So far so good. We have designed both our RecyclerView and CardView. How do we make our RecyclerView display cards for each list item? We need three things:

1. An Object for each list item

We want to display a list of colors (Palettes), so we define a Palette object. Each palette has a name, a hexadecimal value, and an int value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
publicclassPalette {
    privateString name;
    privateString hexValue;
    privateintintValue;
 
    publicPalette(String name, String hexValue, intintValue) {
        this.name = name;
        this.hexValue = hexValue;
        this.intValue = intValue;
    }
 
    publicString getName() {
        returnname;
    }
 
    publicString getHexValue() {
        returnhexValue;
    }
 
    publicintgetIntValue() {
        returnintValue;
    }
}

2. A ViewHolder, that holds a card (and the card's data)

We define a ViewHolder. The ViewHolder's constructor receives a View object, which in our case would be our defined CardView (card_view.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
publicclassPaletteViewHolder extendsRecyclerView.ViewHolder {
 
    protectedTextView titleText;
    protectedTextView contentText;
    protectedCardView card;
 
    publicPaletteViewHolder(View itemView) {
        super(itemView);
        titleText = (TextView) itemView.findViewById(R.id.title);
        contentText = (TextView) itemView.findViewById(R.id.content);
        card = (CardView) itemView;
    }
}

3. An Adapter, that maps list item objects to ViewHolder objects

The Adapter must be a class that extends RecyclerView.Adapter (where T is your ViewHolder class).
Your Adapter should have three new methods as follows.
  • onCreateViewHolder, where you specify the CardView to be used.
1
2
3
4
5
6
7
8
@Override
publicPaletteViewHolder onCreateViewHolder(ViewGroup viewGroup, inti) {
    View itemView = LayoutInflater.
            from(viewGroup.getContext()).
            inflate(R.layout.card_view, viewGroup, false);
 
    returnnewPaletteViewHolder(itemView);
}
  • onBindViewHolder, where you map each Object's data to the corresponding widget in the CardView.
1
2
3
4
5
6
7
@Override
publicvoidonBindViewHolder(PaletteViewHolder paletteViewHolder, inti) {
    Palette palette = palettes.get(i);
    paletteViewHolder.titleText.setText(palette.getName());
    paletteViewHolder.contentText.setText(palette.getHexValue());
    paletteViewHolder.card.setCardBackgroundColor(palette.getIntValue());
}
  • getItemCount, which returns the number of items in your list.
The code for our example is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
publicclassMyRecyclerAdapter extendsRecyclerView.Adapter {
 
    privateList palettes;
 
    publicMyRecyclerAdapter(List palettes) {
        this.palettes = newArrayList();
        this.palettes.addAll(palettes);
    }
 
    @Override
    publicPaletteViewHolder onCreateViewHolder(ViewGroup viewGroup, inti) {
        View itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.card_view, viewGroup, false);
 
        returnnewPaletteViewHolder(itemView);
    }
 
    @Override
    publicvoidonBindViewHolder(PaletteViewHolder paletteViewHolder, inti) {
        Palette palette = palettes.get(i);
        paletteViewHolder.titleText.setText(palette.getName());
        paletteViewHolder.contentText.setText(palette.getHexValue());
        paletteViewHolder.card.setCardBackgroundColor(palette.getIntValue());
    }
 
    @Override
    publicintgetItemCount() {
        returnpalettes.size();
    }
}

Running the Program

At this point, we have completed the integration of both RecyclerView and CardView except for one small step. Our RecyclerView must be connected to its Adapter. This is done from the Activity that should display the list. In the onCreate method, we inflate the RecyclerView.
The RecyclerView requires a LayoutManager (NOTE: requires). The APIs currently provide a default LayoutManager (LinearLayoutManager), which determines how the contents of the list are positioned on the list. We inflate the RecyclerView, set the LayoutManager, and call setAdapter to set its adapter to an instance of our adapter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
publicclassMainActivity extendsActionBarActivity {
 
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerList);
        LinearLayoutManager llm = newLinearLayoutManager(this);
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(llm);
 
        recyclerView.setAdapter(newMyRecyclerAdapter(generatePalettes()));
    }
 
    privateArrayList generatePalettes() {
        ArrayList palettes = newArrayList<>();
        palettes.add(newPalette("RED", "#D32F2F", Color.parseColor("#d32f2f")));
        palettes.add(newPalette("PINK", "#FF4081", Color.parseColor("#ff4081")));
        palettes.add(newPalette("INDIGO", "#7B1FA2", Color.parseColor("#7b1fa2")));
        palettes.add(newPalette("BLUE", "#536DFE", Color.parseColor("#536dfe")));
        palettes.add(newPalette("GREEN", "#388E3C", Color.parseColor("#388e3c")));
        palettes.add(newPalette("ORANGE", "#FF5722", Color.parseColor("#ff5722")));
        palettes.add(newPalette("AMBER", "#FFA000", Color.parseColor("#ffa000")));
        returnpalettes;
    }
}

Conclusion


RecyclerView is the correct (and efficient) way to create lists in your Android app. Using a CardView with a RecyclerView enables developers to build high quality apps that display lists of items quickly and easily.
I am very interested in learning of a corner case where a ListView would be a better fit than a RecyclerView.

Viewing all articles
Browse latest Browse all 1406

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>