How to create custom CardViews in Android

- Andrés Cruz

En español
How to create custom CardViews in Android

In this post we will see how to create custom CardViews, for this we will only focus on creating the view and we will not work on any other component of the Android application (like the activity) or anything like that, the idea is to focus on how to create a layout complete for a list that can have several options, some basic information and a highlighted field.

CardViews are great containers for displaying data in a summary and detailed way; they are widely used to create the elements of the lists through the What's new in Material Design: The RecyclerView.

As you can see in the promotional image, there are certain elements aligned in a way that at first glance may not be so easy to deduce their organization but in reality its construction is not complex.

Summarizing a bit and indicating each of the elements in the following image in descending order, our view will have 3 main sections:

  1. Featured section.
  2. The CardView as such.
  3. The options section.
cardview estructura en android

What is a CardView for?

The CardViews are a design element that have a native widget-like design with the typical shading and rounded edges and are widely used in conjunction with the RecycleViews that we have already discussed in a previous post.

As mentioned above, it contains a number of unique properties such as border rounding, a property to change the background color etc; you can consult the official documentation for more information Create lists and cards.

Creating our CardView

Finally, we proceed to detail the steps necessary to create the previous CardView; As parent container to the CardView we will define a RelativeLayout; the reason, its facility to align elements with floating content in practically any position.

Within the same RelativeLayout container we will define 3 more blocks:

  1. Another parent container inside the CardView that will be a RelativeLayout for top margin handling.
  2. Another container for the highlighted section of the CardView (TextView) that will allow the TextView to be centrally aligned.
  3. A LinearLayout that will contain some floating buttons for the purpose of managing the section of options allowed by the user.

Creating the options section

In this block we define a margin to give the typical effect that the highlighted section protrudes from the CardView (half inside the container and half outside) and the LinearLayout with the property android:orientation="horizontal" allows to align all the elements contained within it horizontally.

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rlContainer"
        android:layout_centerHorizontal="true"
        android:layout_marginRight="@dimen/fab_margin"
        android:layout_marginTop="-15dp"
        android:orientation="horizontal">

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabInfo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/fab_margin"
            android:src="@drawable/ic_action_info_outline"
            app:fabSize="mini" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_action_edit"
            app:fabSize="mini" />
    </LinearLayout>

Creating the Featured Section

We will now create the featured section consisting of a centered TextView; for this, the RelativeLayout parent container must occupy the entire width and together with the property android:layout_centerHorizontal="true" it allows to align the TextView in the middle, from here we put a padding of 10dp to make the balloon a little more attractive and a margin that allows us to have our featured section centered.

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="25dp">

        <TextView
            android:id="@+id/tvMount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:background="@drawable/layout_bg_corner_mount_1"
            android:fontFamily="sans-serif-thin"
            android:padding="10dp"
            android:text="title"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="#FFFFFF"
            android:textSize="25dp" />
    </RelativeLayout>

Designing the rest of the CardView

Now the last thing we need is to create the central and main section of our list whose code is not complicated and does not need further information:

    <RelativeLayout
        android:id="@+id/rlContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="@dimen/space_component3x"
        android:layout_marginRight="@dimen/space_component3x"
        android:layout_marginTop="0dp">

        <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:id="@+id/cvContainer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/card_detail_mount_margin"
            android:foreground="?android:attr/selectableItemBackground"
            card_view:cardCornerRadius="5dp">

            <LinearLayout
                android:id="@+id/llContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:orientation="vertical"
                android:padding="@dimen/pad_10dp">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:id="@+id/tvCount"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentLeft="true"
                        android:fontFamily="sans-serif-light"
                        android:text="title"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#FFFFFF"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/tvDate"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:fontFamily="sans-serif-light"
                        android:gravity="right"
                        android:text="title"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#FFFFFF"
                        android:textStyle="bold" />
                </RelativeLayout>

                <TextView
                    android:id="@+id/tvTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="@dimen/pad_5dp"
                    android:layout_marginTop="@dimen/space_component3x"
                    android:layout_toLeftOf="@+id/tvDate"
                    android:fontFamily="sans-serif-condensed"
                    android:text="title"
                    android:textColor="#FFFFFF"
                    android:textSize="20dp" />

                <TextView
                    android:id="@+id/tvDirection"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:fontFamily="sans-serif-light"
                    android:text="title"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:textColor="#FFFFFF"
                    android:textSize="@dimen/abc_text_size_small_material" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/space_big"
                    android:orientation="vertical" />

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

    </RelativeLayout>

Finally the complete code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rlFcontainer"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/rlContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="@dimen/space_component3x"
        android:layout_marginRight="@dimen/space_component3x"
        android:layout_marginTop="0dp">

        <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:id="@+id/cvContainer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/card_detail_mount_margin"
            android:foreground="?android:attr/selectableItemBackground"
            card_view:cardCornerRadius="5dp">

            <LinearLayout
                android:id="@+id/llContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:orientation="vertical"
                android:padding="@dimen/pad_10dp">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:id="@+id/tvCount"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentLeft="true"
                        android:fontFamily="sans-serif-light"
                        android:text="title"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#FFFFFF"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/tvDate"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:fontFamily="sans-serif-light"
                        android:gravity="right"
                        android:text="title"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#FFFFFF"
                        android:textStyle="bold" />
                </RelativeLayout>

                <TextView
                    android:id="@+id/tvTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="@dimen/pad_5dp"
                    android:layout_marginTop="@dimen/space_component3x"
                    android:layout_toLeftOf="@+id/tvDate"
                    android:fontFamily="sans-serif-condensed"
                    android:text="title"
                    android:textColor="#FFFFFF"
                    android:textSize="20dp" />

                <TextView
                    android:id="@+id/tvDirection"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:fontFamily="sans-serif-light"
                    android:text="title"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:textColor="#FFFFFF"
                    android:textSize="@dimen/abc_text_size_small_material" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/space_big"
                    android:orientation="vertical" />

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

    </RelativeLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rlContainer"
        android:layout_centerHorizontal="true"
        android:layout_marginRight="@dimen/fab_margin"
        android:layout_marginTop="@dimen/negative_margin_design_fab_size_mini"
        android:orientation="horizontal">

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabInfo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/fab_margin"
            android:src="@drawable/ic_action_info_outline"
            app:fabSize="mini" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_action_edit"
            app:fabSize="mini" />
    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/space_component5x">

        <TextView
            android:id="@+id/tvMount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:background="@drawable/layout_bg_corner_mount_1"
            android:fontFamily="sans-serif-thin"
            android:padding="@dimen/space_component2x"
            android:text="title"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="#FFFFFF"
            android:textSize="@dimen/card_detail_mount_text_size" />
    </RelativeLayout>
</RelativeLayout>

Values of dimen.xml

  • <dimen name="space_component">5dp</dimen>
  • <dimen name="space_component2x">10dp</dimen>
  • <dimen name="space_component3x">15dp</dimen>
  • <dimen name="space_component5x">25dp</dimen>
  • <dimen name="fab_margin">10dp</dimen>
  • <dimen name="space_big">20dp</dimen>
  • <dimen name="card_detail_mount_margin">45dp</dimen>
  • <dimen name="card_detail_mount_text_size">25dp</dimen>

Resources and colors

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorFive"/>
    <stroke android:width="3dp" android:color="@color/colorFive" />
    <corners android:radius="30dp"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
<color name="colorFive">#F7C51E</color>

(Optional) Fonts in Android

To give it some style, and as you can see in the code sections above, the font was changed when considering doing so; the following types of typography that we can use in Android:

android:fontFamily="sans-serif"           // roboto regular
android:fontFamily="sans-serif-light"     // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-black"     // roboto black
android:fontFamily="sans-serif-thin"      // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium"    // roboto medium (android 5.0)

Represented in the following image:

Tipografía en android

You can see the complete explanation in the following link: service. How to change fontFamily of TextView in Android.

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.