Open In App

How to Build Material and Dark Themes Apps Using Style in Android?

Last Updated : 15 May, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

In order to increase the user traffic of the android application, there is a need of tweaking the Theme and the Style of the android application. In today’s mobile application development one also need to consider the look and feel of the application. One major feature in the application user needs is the Dark Theme. The default theme for the Android devices was dark until Android lollipop(5.0) but the Android Q released in the 3rd quarter of 2019. The majority of the applications implemented their dark theme version of the application. In this article, it’s been illustrated how to implement the Material Dark theme version of the Android Application.

Why Dark Theme?

Dark themes reduce the luminance emitted by mobile device screens, hence reducing eye strain. Also maintaining the minimum color contrast. This also helps in the functional design of the application. Consuming less battery power, adjusting to the current condition of light. Devices with OLED displays can get befit of the Dark themes. Most importantly, there are more fans for the Dark theme version of the application.

Understanding the difference between styles and themes

  • Android developers witness the ambiguity in styles and themes. The reason is that in Android there are only tag names <style>, there is no <theme> tag available.
  • Style is a collection of attributes that define the appearance of a single view. The style attributes are the font, color, size, background color, etc. For example, the font size may be different for heading and body.
  • Theme, on the contrary, is applied to the entire app, or activity, or view hierarchy, not just for individual views. Themes can also apply styles to non-view elements such as status bar, window background, etc. For example, the colorPrimary is applied to all the Floating Action Buttons or Normal Buttons of the entire application. One can get the difference in the following image.

  • The above image clearly can see the difference between, The Styles and the Theme. Where the style is applied for the particular view inside the parent View group, but the theme is applied to the entire parent view group.
  • But Styles and Themes go hand in hand For Example the Floating Action Button and Normal clickable buttons can have different colors like colorPrimary, and colorSecondary respectively.

Material Theming Properties

The Main 3 properties to achieve functional material theme in Android application are:

  1. Color
  2. Typography
  3. Shape
  4. Material Design Components
  • One can get the basic information about these properties can refer to Introduction to Material Design in Android
  • One may have seen in the recent update of Android studio (4.1 and above) The Color properties are made different. Those are:

Primary Color Variants:

Attribute

Description

Default Value

colorPrimary  This color primary color of the application. This color is the most used color in the Application. This can also be called a branding color #FF6200EE
colorPrimaryVariant  This is the variant of the colorPrimary. This may be a lighter or darker variant of the primary color. #FF3700B3
colorOnPrimary The name itself indicates the color should be assigned to those elements which are above the colorPrimary. #FFFFFFFF

Secondary Color Variants:

Attribute

Description

Default Value

colorSecondary The color which is most used after the colorPrimary. This color is accented complement color of the colorPrimary. #FF03DAC5
colorSecondaryVariant This is  a variant of the colorSecondary. This may be a lighter or darker variant of the colorSecondary. #FF018786
colorOnSecondary This name also indicates that the color should be assigned to those elements which are above the colorSecondary. #FF000000

Surface Colors:

Attribute

Description

Default Value

colorSurface  Surface color that affects surface components, such as cards, sheets, menus. #FFFFFF
colorOnSurface  This color assigned to the texts or icons which are above the colorSurface  #000000

Colors for Errors:

Attribute Description Default Value
colorError This indicated the color assigned to elements which state, the error. #B00020
colorOnError The color which is assigned to texts or icons which are above the colorError. #FFFFFF

Typography:

There are predefined and well-engineered typography variants of the text in the Material Design Typography system. Have look at the following image:

These are by default are the attributes that come with the Material Design theme, and can be applied directly to the TextViews according to the context of the Text in the application.

Steps to implement the Dark Theme variant of the Application

Step 1: Create empty activity Android Studio project:

Create an empty activity Android Studio project and select Kotlin as the programming language. Refer to Android | How to Create/Start a New Project in Android Studio?.

Step 2: Add the required dependency

  • Add the following dependency to the app-level gradle file, and sync the project.
  • This dependency, however, is added by default when the new Android Studio(version 4.0 and above) project is created.

implementation ‘com.google.android.material:material:1.3.0-alpha04’

Step 3: Adding the Primary and Secondary brand colors

  • We need to primarily decide the Primary and Secondary color, and take the color code out of it. In this case, The Primary Color is green and complement to it there is red_200 and red_700 as Secondary brand colors.
  • One can make their own color swatches and combination using either this or this.
  • Invoke the following colors to implement the same in the application inside the colors.xml file.

XML




<?xml version="1.0" encoding="utf-8"?>
<resources>
  
    <!--Primary colors of the application-->
    <color name="green_200">#98d5b0</color>
    <color name="green_light">#e5f5eb</color>
    <color name="green_500">#18ad62</color>
    <color name="green_700">#008c4c</color>
  
    <!--Secondary brand color of the application-->
    <color name="red_200">#eb8baf</color>
    <color name="red_700">#b31058</color>
  
    <!--Other surface colors and red for error color-->
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="red">#B00020</color>
  
</resources>


Step 4: Working with the themes.xml files

  • Firstly, applying the DayNight DarkActionBar Theme to both light theme and Dark theme of the application as follows:

<style name=”Theme.GFGArticle” parent=”Theme.MaterialComponents.DayNight.DarkActionBar”>

  • Following the Color System provided by Material Design Guidelines as discussed above the following are the color system applied for the light theme and dark theme of the application.
  • The following values\theme.xml is applied when the application is under the light theme.

XML




<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.GFGArticle" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/green_500</item>
        <item name="colorPrimaryVariant">@color/green_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>


  • The following values-night\themes.xml is applied when the application is under dark theme.

XML




<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.GFGArticle" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/green_200</item>
        <item name="colorPrimaryVariant">@color/green_700</item>
        <item name="colorOnPrimary">@color/black</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/red_200</item>
        <item name="colorSecondaryVariant">@color/red_200</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>


  • Have a look at the following images where these files reside inside the Android Studio Project.

Step 5: Working with activity_main.xml file

  • The main layout of the application consists of the Material Design Type system. And one Extended Floating Action Button and one Normal Floating Action Button to Demonstrate The secondary brand color of the application.
  • All the text views in the layout inherit the style of the Material type system. For example – “style=”@style/TextAppearance.MaterialComponents.Headline4”.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    tools:ignore="HardcodedText">
  
    <!--Switch button to toggle between the Light and Dark Mode-->
    <com.google.android.material.switchmaterial.SwitchMaterial
        android:id="@+id/switchMaterial"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:checked="false"
        android:text="SWITCH TO DARK MODE"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        android:padding="16dp"
        app:layout_constraintBottom_toTopOf="@+id/extendedFloatingActionButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/switchMaterial">
  
        <!--TextView with the Headline 4 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Headline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="HEADLINE 4" />
  
        <!--TextView with the Headline 5 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Headline5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="HEADLINE 5" />
  
        <!--TextView with the Headline 6 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Headline6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="HEADLINE 6" />
  
        <!--TextView with the Subtitle 1 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Subtitle1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SUBTITLE 1" />
  
        <!--TextView with the Subtitle 2 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Subtitle2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SUBTITLE 2" />
  
        <!--TextView with the Body 1 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Body1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Body 1" />
  
        <!--TextView with the Body 2 as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Body2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Body 2" />
  
        <!--TextView with the Buttons as Material type system-->
        <!--However this type system is applied to text inside the buttons only-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TEXT VIEW FOR BUTTON" />
  
        <!--TextView with the Caption as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Caption"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Caption" />
  
        <!--TextView with the Overline texts as Material type system-->
        <TextView
            style="@style/TextAppearance.MaterialComponents.Overline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="OVERLINE" />
  
        <!--Buttons to demonstrate, how Material dark theme changes
             the primary color's contrast
            when switched from light theme to dark theme-->
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BUTTON 1" />
  
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BUTTON 2" />
  
    </LinearLayout>
  
    <!--Floating action buttons to demonstrate how the 
        secondary brand color of the application can be used-->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:src="@drawable/ic_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
  
    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
        android:id="@+id/extendedFloatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="EXTENDED FAB"
        app:icon="@drawable/ic_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


Output UI:

Step 6: Working with the MainActivity.kt file

Inside the MainActivity.kt file it’s been handled the checked change listener of the material switch button. And if the device won’t support the dark theme of the application, this project itself supports the dark theme version for all kinds of APIs.

Kotlin




package com.aditya.gfgarticle
  
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate
import com.google.android.material.switchmaterial.SwitchMaterial
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // Instance for the material switch
        val switchMaterial: SwitchMaterial = findViewById(R.id.switchMaterial)
  
        // handle the checked changes for the material switch
        switchMaterial.setOnCheckedChangeListener { buttonView, isChecked ->
            when (isChecked) {
                // if checked toggle to dark mode
                true -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
  
                // if unchecked toggle back to light mode
                false -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            }
        }
    }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads