android-cardview-demo

Android Cardview tutorial with example

Introduction

In previous tutorials we learnt horizontal list and vertical list using recyclerview. This Android tutorial is to add cardview in apps with recyclerview. An example app has been developed to demonstrate the concepts of Android Cardview.

Cardview is a very powerful UI tool. You may add photo, texts, links etc in a card to give your user one nice representation of the information you want to share. By combining recyclerview and cardview, we can give our apps a beautiful representation. While, I am no UX designer, I will cover the necessary points for you to explore your own creativity. So, without further ado, let’s get started.

App Demo

Before we start with the development, let’s first take a look as to what we are going to create as part of this tutorial.

android-cardview-demo

android-cardview-demo

Tech Stack

We have used following tech stack in this app

Android Studio 3.1
JAVA for Android programming

 

Basic tasks for implementing cardview

Following are the  basic tasks while implementing cardview –

  1. Add the dependency for cardview and recyclerview.
  2. Write a model class for the information  you want to display in the cardview. In my case it’s grocery items
  3. Write a XML layout file to depict information visually on the card view/recycler view.
  4. Write a custom adapter to inflate the recyclerview.
  5. Modify the acitivity_main.xml to include recyclerview
  6. And finally harness these changes from MainActivity.java; populate data
  7. And that’s it. You just understood the basic skeleton of a cardview project.

Let’s get started!

Create an empty project

  • Launch Android Studio and click: File –> New –> New Project…
  • A “Create New Project” dialog box will open; we’ll provide the app name and company domain. I have entered following details, you can provide the name/domain as per your choice and preference.
    • Application Name:- ItcCardView
    • Company Domain:- iteritory.com
  • Click on Next button. In the next window, select the minimum SDK version; you can choose as per your preference. In this case, I have chosen API 16: Android 4.1 (Jelly Bean). Click Next button.
  • In the next window, select “Empty Activity“. Click Next button.
  • In the next window,  let’s keep the Activity Name and Layout Name to default. Click Finish button.
  • I’ll change the app name a bit here, traverse and open res–> values –> strings.xml. Find the line with app_name attribute. Change the value to “My CardView App”.

Add CardView dependency

Now, in order to use cardview in your app, we will add the dependencies for cardview, recyclerview in the app level build.gradle file. After adding the necessary dependencies, my build.gradle file looks like –

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.iteritory.itccardview"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.0'
    implementation 'com.android.support:cardview-v7:27.1.0'
    implementation 'com.android.support:recyclerview-v7:27.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

Add CardView to the layout file

Next, we will add the CardView widget in the layout file. Inside the CardView widget, we can use the container view like LinearLayout or RelativeLayout as the child. Inside the container view, we can add the other widgets to represent image, text, button etc. For now, let’s just create a simplest cardview app with a simple text. Open the activity_main.xml and modify it; add the cardview widget. After doing the necessary modification, my activity_main.xml looks like –

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.CardView
        android:id="@+id/idCardView"
        android:layout_margin="20dp"
        android:layout_width="250dp"
        android:layout_height="250dp"
        app:cardCornerRadius="4dp">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Hello World! This is the initial card view!!" />
    </android.support.v7.widget.CardView>
</LinearLayout>

Now, fire up the app from android studio; the simple app will look like –

android-cardview-first-demo

android-cardview-first-demo

Cool!! so far so good. Now, we will do some coding to demonstrate the power of cardview widget. Here in this demo, we will create a list of products in an arbitrary e-commerce app.

Write a Model Class depicting Product

Now, we will write a model class depicting the grocery item. We’ll use following fields –

  • an image to display the picture of the grocery product
  • Product name
  • Price
  • Weight
  • Quantity

Create a new package inside com.iteritory.itccardview with the name model. Create Grocery.java model class inside this newly created package. The class looks like –

package com.iteritory.itccardview.model;


public class Grocery {
    public int productImage;
    public String productName;
    public String productPrice;
    public String productWeight;
    public String productQty;

    public Grocery(String productName, int productImage, String productPrice, String productWeight, String productQty) {
        this.productImage = productImage;
        this.productName = productName;
        this.productPrice = productPrice;
        this.productWeight = productWeight;
        this.productQty = productQty;
    }

    public String getProductQty() {
        return productQty;
    }

    public void setProductQty(String productQty) {
        this.productQty = productQty;
    }

    public String getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(String productPrice) {
        this.productPrice = productPrice;
    }

    public String getProductWeight() {
        return productWeight;
    }

    public void setProductWeight(String productWeight) {
        this.productWeight = productWeight;
    }

    public int getProductImage() {
        return productImage;
    }

    public void setProductImage(int productImage) {
        this.productImage = productImage;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }
}

 

Write a Layout XML depicting Product

Now, we will write a layout file that will depict one grocery item in the list. Under the res -> layout folder, create a new file with name layout_product_card.xml. After the necessary updates, my layout looks as follows –

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">
        <android.support.v7.widget.CardView
            android:id="@+id/idCardView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:elevation="7dp"
            android:layout_margin="7dp"
            app:cardCornerRadius="6dp"
            app:cardPreventCornerOverlap="false">

            <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@color/cardview_light_background"
                android:orientation="horizontal"
                android:padding="10dp">

                <!-- Product Image -->

                <LinearLayout
                    android:id="@+id/idLinearLayoutProductImage"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true">
                    <ImageView
                        android:id="@+id/idProductImage"
                        android:layout_width="50dp"
                        android:layout_height="50dp"/>
                </LinearLayout>

                <!-- Rest of the product info and add/remove to/from cart symbols -->

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:orientation="horizontal"
                    android:id="@+id/idTopLayout">

                        <TextView
                            android:id="@+id/idProductName"
                            android:layout_width="250dp"
                            android:layout_height="wrap_content"
                            android:layout_alignParentTop="true"
                            android:layout_toRightOf="@+id/idLinearLayout"
                            android:gravity="center_vertical|center_horizontal"
                            android:textSize="25dp"
                            tools:textColor="@android:color/black" />

                        <ImageView
                            android:id="@+id/idMinusICon"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:src="@drawable/minus_circle" />
                        <TextView
                            android:id="@+id/idProductQty"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical|center_horizontal"
                            android:textSize="20dp"
                            tools:textColor="@android:color/black"
                            android:textStyle="bold" />
                        <ImageView
                            android:id="@+id/idPlusIcon"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:src="@drawable/plus_circle" />
                    </LinearLayout>

                    <LinearLayout
                        android:id="@+id/idBottomLayout"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:layout_below="@+id/idTopLayout">

                    <TextView
                        android:id="@+id/idProductPrice"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_horizontal|center_vertical"
                        android:layout_marginLeft="100dp"
                        android:layout_weight="1"
                        android:paddingRight="15dp"
                        android:textSize="15dp"
                        android:textStyle="bold"
                        tools:textColor="@android:color/black" />

                    <TextView
                        android:id="@+id/idProductWeight"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right|center_vertical"
                        android:paddingRight="45dip"
                        android:textSize="15dp"
                        android:textStyle="bold"
                        tools:textColor="@android:color/black" />
                </LinearLayout>
        </RelativeLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

 

Write custom adapter for the recyclerview

Next, we will create a custom adapter class that will inflate the layout file layout_product_card.xml (that we created above). Create a new package called adapter inside com.iteritory.itccardview. Write the adapter class inside adapter package.

The custom adapter class extends RecyclerView.Adapter and overrides 3 methods –

  1. onCreateViewHolder() – inflates the layout_product_card.xml layout
  2. onBindViewHolder() – the data (product image, product name etc) is retrieved from the object and is set to each item/row in the list. We’ll also override imageView onClick method to display a toast saying which item is selected.
  3. getItemCount() – returns the numbers of items/rows in the list.

So folks, let’s crack some code.

package com.iteritory.itccardview.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.iteritory.itccardview.R;
import com.iteritory.itccardview.model.Grocery;

import java.util.List;

public class GroceryProductAdapter extends RecyclerView.Adapter<GroceryProductAdapter.GroceryProductViewHolder>{
    private List<Grocery> grocderyItemList;
    Context context;

    public GroceryProductAdapter(List<Grocery> grocderyItemList, Context context) {
        this.grocderyItemList = grocderyItemList;
        this.context = context;
    }

    @Override
    public GroceryProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //inflate the layout file
        View groceryProductView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_product_card, parent, false);
        GroceryProductViewHolder gvh = new GroceryProductViewHolder(groceryProductView);
        return gvh;
    }

    @Override
    public void onBindViewHolder(GroceryProductViewHolder holder, final int position) {
        holder.imageProductImage.setImageResource(grocderyItemList.get(position).getProductImage());
        holder.txtProductName.setText(grocderyItemList.get(position).getProductName());
        holder.txtProductPrice.setText(grocderyItemList.get(position).getProductPrice());
        holder.txtProductWeight.setText(grocderyItemList.get(position).getProductWeight());
        holder.txtProductQty.setText(grocderyItemList.get(position).getProductQty());

        holder.imageProductImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String productName = grocderyItemList.get(position).getProductName().toString();
                Toast.makeText(context, productName + " is selected", Toast.LENGTH_SHORT).show();
            }
        });
    }

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

    public class GroceryProductViewHolder extends RecyclerView.ViewHolder {
        ImageView imageProductImage;
        TextView txtProductName;
        TextView txtProductPrice;
        TextView txtProductWeight;
        TextView txtProductQty;
        public GroceryProductViewHolder(View view) {
            super(view);
            imageProductImage=view.findViewById(R.id.idProductImage);
            txtProductName=view.findViewById(R.id.idProductName);
            txtProductPrice = view.findViewById(R.id.idProductPrice);
            txtProductWeight = view.findViewById(R.id.idProductWeight);
            txtProductQty = view.findViewById(R.id.idProductQty);
        }
    }
}

Change activity_main.xml to add recyclerview

Now, we will make minor modification in the activity_main.xml file to add the recyclerview. Post change, the file content looks like –

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/idRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:scrollbars="vertical" />
</LinearLayout>

Update MainActivity.java to add data and populate the cardview

Finally it’s time to update MainActivity.java file to harness all these activities that we did so far. Let’s take a look at the code –

package com.iteritory.itccardview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import com.iteritory.itccardview.adapter.GroceryProductAdapter;
import com.iteritory.itccardview.model.Grocery;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private GroceryProductAdapter mAdapter;
    private List<Grocery> mProductList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //getting the recyclerview from xml
        mRecyclerView = (RecyclerView) findViewById(R.id.idRecyclerView);
        //mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        //Populate the products
        mProductList = new ArrayList<>();
        mProductList.add(new Grocery("Mango",R.drawable.mango,"Rs. 150", "1 kg", "5"));
        mProductList.add(new Grocery("Pineapple",R.drawable.pineapple,"Rs. 250", "500 gm", "2"));

        //set adapter to recyclerview
        mAdapter = new GroceryProductAdapter(mProductList,this);
        mRecyclerView.setAdapter(mAdapter);
    }
}

GitHub Info

The project is checked in to GitHub link –> https://github.com/msadrud/ItcCardView

Feel free to take a look.

Reference

For the UI part, I referenced to another blog from http://www.tutorialsface.com. I have modified the UI layout a little bit to make it simpler.

However, I thank http://www.tutorialsface.com folks for the fantastic content in their site.

For icons and images; I have referred to google search; you can get the icon and images from github link shared above.

Conclusion

So folks that’s it! In this tutorial we learnt a bit about card view. Do let me know how you liked the tutorial should it have helped you anyway. 🙂

225

2 Responses

  1. Milan Bamaniya
    December 9, 2019
  2. Alexanderasdfasdf
    November 5, 2021

Write a response

This site uses Akismet to reduce spam. Learn how your comment data is processed.