How to create an Expandable CardView in Android

18 Feb, 2021
Expandable Cardview provides to create expansion panels without too much hassle and without writing boilerplate code. An expandable card-view becomes quite useful when it comes to an efficient and systematic presentation of data or information on the screen. It is used in a variety of apps, for example, the Contacts app or the Gallery app. Here, in this tutorial, we’ll create a simple Expandable CardView in Android using Java.
Step 1: Create a New Project in Android Studio
Click on File, then New => New Project.Choose “Empty Activity” for the project template.Select language as Java.Select the minimum SDK as per your need.
Click on File, then New => New Project.
Choose “Empty Activity” for the project template.
Select language as Java.
Select the minimum SDK as per your need.
Step 2: Add the CardView Dependency
To be able to use the CardView element, you’ll first have to add it’s dependency in the project. In the build.gradle (Module: app) file add the following dependency and click on Sync now to synchronize the changes made.
implementation ‘androidx.cardView:cardView:1.0.0’
Step 3: Add all the Required Drawable Resources in the Drawable Folder
Choose the drawable resources as per the requirement. Here, in the CardView, use two images of the GeeksforGeeks icons and 2 other icons to indicate either of the ‘expand more’ or ‘expand less’ options. The following are the geeksforgeeks icons used:
The image below shows the use of expansion icons:
The expansion icons used here are imported as a vector asset from the Android Studio itself. The steps for the same are as follows:
Right-click on the drawable resource folder.Go to new.Click on Vector Asset.The following box pops up. Click on the icon next to Clip Art.From the variety of icons shown, choose the following two icons:ic_baseline_expand_more_24
ic_baseline_expand_less_24
The following files get added to the drawable folder:ic_baseline_expand_more_24ic_baseline_expand_less_24ic_baseline_expand_more_24<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M16.59, 8.59L12, 13.17 7.41,                        8.59 6, 10l6, 6 6, -6z"/></vector>ic_baseline_expand_less_24<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M12, 8l-6, 6 1.41, 1.41L12,                       10.83l4.59, 4.58L18, 14z"/></vector>
Right-click on the drawable resource folder.
Go to new.
Click on Vector Asset.
The following box pops up. Click on the icon next to Clip Art.
From the variety of icons shown, choose the following two icons:ic_baseline_expand_more_24
ic_baseline_expand_less_24
The following files get added to the drawable folder:ic_baseline_expand_more_24ic_baseline_expand_less_24ic_baseline_expand_more_24<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M16.59, 8.59L12, 13.17 7.41,                        8.59 6, 10l6, 6 6, -6z"/></vector>ic_baseline_expand_less_24<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M12, 8l-6, 6 1.41, 1.41L12,                       10.83l4.59, 4.58L18, 14z"/></vector>
ic_baseline_expand_more_24
ic_baseline_expand_less_24

The following files get added to the drawable folder:
ic_baseline_expand_more_24
ic_baseline_expand_less_24
<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M16.59, 8.59L12, 13.17 7.41,                        8.59 6, 10l6, 6 6, -6z"/></vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24"    android:viewportHeight="24"    android:tint="?attr/colorControlNormal"><path    android:fillColor="@android:color/white"    android:pathData="M12, 8l-6, 6 1.41, 1.41L12,                       10.83l4.59, 4.58L18, 14z"/></vector>
Step 4: Modify the XML Layout
In the XML file, create the entire layout along with the portion that you want to be displayed after the CardView is expanded. The basic idea here is to set the visibility of the expandable element to ‘gone’ or ‘visible’.
Note: Set the visibility to ‘gone’ and not ‘invisible’ because ‘gone’ removes that particular element completely as if it was never there. However, ‘invisible’ only makes the element disappears while it still exists in the layout.
In the below layout, expanded the CardView to display a list of three subjects. The following is the code for activity_main.xml file.
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout     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"    android:background="#E4E3E3"    tools:context=".MainActivity">      <!--Base CardView-->    <androidx.cardview.widget.CardView        android:id="@+id/base_cardview"        style="@style/Base.CardView"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintHorizontal_bias="0.473"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintVertical_bias="0.021">          <!--This is a ConstraintLayout for the entire CardView                    including the expandable portion-->        <androidx.constraintlayout.widget.ConstraintLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            app:layout_constraintBottom_toBottomOf="@+id/base_cardview"            app:layout_constraintTop_toTopOf="parent"            app:layout_constraintVertical_bias="0.511"            tools:layout_editor_absoluteX="-55dp">              <!--This is a ConstraintLayout for the fixed portion                of the CardView. The elements                 that lie within the fixed portion of the CardView                can be constrained to this layout.-->            <androidx.constraintlayout.widget.ConstraintLayout                android:id="@+id/fixed_layout"                android:layout_width="match_parent"                android:layout_height="150dp"                app:layout_constraintBottom_toBottomOf="parent"                app:layout_constraintEnd_toEndOf="parent"                app:layout_constraintHorizontal_bias="0.0"                app:layout_constraintStart_toStartOf="parent"                app:layout_constraintTop_toTopOf="parent"                app:layout_constraintVertical_bias="0.0">                    <ImageView                    android:id="@+id/icon"                    android:layout_width="150dp"                    android:layout_height="150dp"                    android:src="@drawable/icon_one"                    app:layout_constraintBottom_toBottomOf="@+id/fixed_layout"                    app:layout_constraintEnd_toEndOf="@+id/fixed_layout"                    app:layout_constraintHorizontal_bias="0.0"                    app:layout_constraintStart_toStartOf="@+id/fixed_layout"                    app:layout_constraintTop_toTopOf="@+id/fixed_layout"                    app:layout_constraintVertical_bias="1.0" />                  <TextView                    android:id="@+id/heading"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="GeeksforGeeks"                    android:textColor="#006600"                    android:textSize="25dp"                    android:textStyle="bold"                    app:layout_constraintBottom_toBottomOf="@+id/fixed_layout"                    app:layout_constraintEnd_toEndOf="@+id/fixed_layout"                    app:layout_constraintHorizontal_bias="0.926"                    app:layout_constraintStart_toStartOf="@+id/fixed_layout"                    app:layout_constraintTop_toTopOf="@+id/fixed_layout"                    app:layout_constraintVertical_bias="0.198" />                  <TextView                    android:id="@+id/list_of_subjects"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_marginTop="20dp"                    android:layout_marginBottom="58dp"                    android:text="List of subjects"                    android:textSize="20dp"                    app:layout_constraintBottom_toBottomOf="@+id/fixed_layout"                    app:layout_constraintEnd_toEndOf="parent"                    app:layout_constraintHorizontal_bias="0.878"                    app:layout_constraintStart_toStartOf="parent"                    app:layout_constraintTop_toBottomOf="@+id/heading"                    app:layout_constraintVertical_bias="0.0" />                  <!--This is ImageButton for the expansion icon.-->                <ImageButton                    android:id="@+id/arrow_button"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:src="@drawable/ic_baseline_expand_more_24"                    app:layout_constraintBottom_toBottomOf="@id/fixed_layout"                    app:layout_constraintEnd_toEndOf="parent"                    app:layout_constraintHorizontal_bias="0.802"                    app:layout_constraintStart_toStartOf="parent"                    app:layout_constraintTop_toBottomOf="@+id/list_of_subjects"                    app:layout_constraintVertical_bias="0.0" />              </androidx.constraintlayout.widget.ConstraintLayout>              <!--The following is the expandable portion whose                 visibility is initially set to 'gone'.                The parent LinearLayout contains 3 child LinearLayouts                that hold a subject name and an icon each.-->            <LinearLayout                android:id="@+id/hidden_view"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="vertical"                android:visibility="gone"                app:layout_constraintBottom_toBottomOf="parent"                app:layout_constraintEnd_toEndOf="parent"                app:layout_constraintStart_toStartOf="parent"                app:layout_constraintTop_toBottomOf="@+id/fixed_layout">                  <!--Child LinearLayout 1-->                <LinearLayout                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:orientation="horizontal">                      <ImageView                        android:layout_width="50dp"                        android:layout_height="50dp"                        android:layout_marginStart="20dp"                        android:layout_marginTop="10dp"                        android:layout_marginEnd="10dp"                        android:layout_marginBottom="10dp"                        android:src="@drawable/gfg_icon_black" />                      <TextView                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:layout_marginStart="20dp"                        android:layout_marginTop="20dp"                        android:text="Database Management"                        android:textColor="#000000"                        android:textSize="20dp" />                </LinearLayout>                  <!--Child LinearLayout 2-->                <LinearLayout                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:orientation="horizontal">                      <ImageView                        android:layout_width="50dp"                        android:layout_height="50dp"                        android:layout_marginStart="20dp"                        android:layout_marginTop="10dp"                        android:layout_marginEnd="10dp"                        android:layout_marginBottom="10dp"                        android:src="@drawable/gfg_icon_black" />                      <TextView                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:layout_marginStart="20dp"                        android:layout_marginTop="20dp"                        android:text="Data Structures"                        android:textColor="#000000"                        android:textSize="20dp" />                </LinearLayout>                  <!--Child LinearLayout 3-->                <LinearLayout                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:orientation="horizontal">                      <ImageView                        android:layout_width="50dp"                        android:layout_height="50dp"                        android:layout_marginStart="20dp"                        android:layout_marginTop="10dp"                        android:layout_marginEnd="10dp"                        android:layout_marginBottom="10dp"                        android:src="@drawable/gfg_icon_black" />                      <TextView                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:layout_marginStart="20dp"                        android:layout_marginTop="20dp"                        android:text="Operating Systems"                        android:textColor="#000000"                        android:textSize="20dp" />                </LinearLayout>            </LinearLayout>          </androidx.constraintlayout.widget.ConstraintLayout>    </androidx.cardview.widget.CardView>  </androidx.constraintlayout.widget.ConstraintLayout>
Step 5: Modify the Java File
In the MainActivity.java, using the if-else statements, specify the conditions to manipulate the visibility of the expandable element.
package com.example.android.expandable_cardview;  import android.os.Bundle;import android.transition.AutoTransition;import android.transition.TransitionManager;import android.view.View;import android.widget.ImageButton;import android.widget.LinearLayout;import androidx.appcompat.app.AppCompatActivity;import androidx.cardview.widget.CardView;  public class MainActivity extends AppCompatActivity {      ImageButton arrow;    LinearLayout hiddenView;    CardView cardView;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);          cardView = findViewById(R.id.base_cardview);        arrow = findViewById(R.id.arrow_button);        hiddenView = findViewById(R.id.hidden_view);          arrow.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                  // If the CardView is already expanded, set its visibility                //  to gone and change the expand less icon to expand more.                if (hiddenView.getVisibility() == View.VISIBLE) {                      // The transition of the hiddenView is carried out                    //  by the TransitionManager class.                    // Here we use an object of the AutoTransition                     // Class to create a default transition.                    TransitionManager.beginDelayedTransition(cardView,                                                   new AutoTransition());                    hiddenView.setVisibility(View.GONE);                    arrow.setImageResource(R.drawable.ic_baseline_expand_more_24);                }                  // If the CardView is not expanded, set its visibility                 // to visible and change the expand more icon to expand less.                else {                      TransitionManager.beginDelayedTransition(cardView,                                                new AutoTransition());                    hiddenView.setVisibility(View.VISIBLE);                    arrow.setImageResource(R.drawable.ic_baseline_expand_less_24);                }            }        });    }}
android
Android-View
Android
How To
Java
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Add Views Dynamically and Store Data in Arraylist in Android?
Android RecyclerView in Kotlin
Android SDK and it's Components
Broadcast Receiver in Android With Example
How to Communicate Between Fragments in Android?
How to Install PIP on Windows ?
How to Find the Wi-Fi Password Using CMD in Windows?
How to install Jupyter Notebook on Windows?
Java Tutorial
How to filter object array based on attributes?