Tutorial Lengkap Penerapan Dark Mode

Dark Mode Android Studio

Dark Mode / Dark Theme / Tema Gelap mulai tersedia pada Android 10 (level API 29) dan lebih tinggi. Lalu bagaimana untuk Android di bawah 10? Tutorial ini akan membahas lengkap bagaimana cara menerapkan Dark Theme pada aplikasi yang akan mengizinkan pengguna aplikasi untuk mengganti tema nya menjadi gelap atau terang sesuai kebutuhan mereka saat aplikasi sedang berjalan.

Dark Theme sendiri memiliki beberapa manfaat, di antara nya:
  • Dapat mengurangi penggunaan daya dengan jumlah yang signifikan (tergantung teknologi layar perangkat).
  • Meningkatkan visibilitas bagi pengguna dengan penglihatan rendah dan mereka yang sensitif terhadap cahaya terang.
  • Membuatnya lebih mudah bagi siapa saja untuk menggunakan perangkat di lingkungan yang kurang cahaya.
Ada beberapa macam dalam penyetelan Dark Mode ini, yaitu :
  1. MODE_NIGHT_NO, untuk menyetel tema ke mode terang.
  2. MODE_NIGHT_YES, untuk menyetel tema ke mode gelap.
  3. MODE_NIGHT_AUTO_BATTERY, disetel oleh penghemat baterai. Mode gelap di hidupkan otomatis saat penghemat baterai smartphone pengguna aktif.
  4. MODE_NIGHT_FOLLOW_SYSTEM, disetel oleh sistem. Mode ini di tentukan oleh waktu pada perangkat pengguna. Saat malam mode gelap akan hidup secara otomatis, dan saat waktu selain malam akan kembali ke mode terang.
Disini kita akan membahas penerapan Dark Mode yang manual, artinya pengguna akan bebas menentukan tema mana yang ingin di pakai, bukan tergantung pada waktu atau penghemat baterai seperti pada nomor 3 dan 4 di atas. Kemudian menyimpan tema yang di pilih menggunakan SharedPreference. Langkah-langkah atau tahapan yang akan kita lakukan adalah sebagai berikut :
  1. Mengganti Style Theme pada style.xml. Untuk menggunakan Dark Theme, parent theme yang di gunakan adalah Theme.AppCompat.DayNight.
  2. Membuat sebuah Class baru yang meng extends Application. Hal ini supaya seluruh activity yang ada pada aplikasi juga mengikuti tema yang di pilih. Penyimpanan tema yang di pilih dengan SharedPreference juga akan di buat di dalam class ini.
  3. Membuat sebuah Activity baru. Hal ini hanya untuk memastikan bahwa tema yang di pilih berhasil di terapkan pada seluruh activity.
  4. Memperbaharui AndroidManifest.xml. Pembaharuan yang di lakukan adalah mendaftarkan class baru yang di buat ke dalam tag <application> </application>, dan juga mendaftarkan activity baru yang di buat.
  5. Selebihnya melakukan kodingan pada activity_main.xml, MainActivity.java dan juga activity_second.xml (nama activity baru yang akan di buat).


Penerapan Dark Mode

Mari kita mulai dengan mengganti style theme yang ada pada style.xml. Letaknya ada pada folder res  > value > styles.xml. Pada langkah ini, cukup hanya mengganti parent theme menjadi Theme.AppCompat.DayNight. Berikut isi dari style.xml pada contoh tutorial ini :

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.DayNight">
        <item name="colorPrimary">#7CB342</item>
        <item name="colorPrimaryDark">#2A282E</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

Lalu buatlah sebuah Class baru, di contoh ini class nya di buat dengan nama ModeGelap.java. Seperti yang di katakan di atas, class ini yang akan merubah tema seluruh activity yang ada pada aplikasi menjadi tema yang di pilih dengan memberi extends Apllication pada class ini. Untuk membuat sebuah class baru, klik kanan pada package project atau MainActivity.java > New > Java Class. Isikan nama laluk klik OK.  Kemudian menyimpan perubahan nya dengan SharedPreference. Berikut isi keseluruhan pada class ModeGelap.java ini :


package com.gwnbs.proyekkeempat;

import android.app.Application;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class ModeGelap extends Application {

    public static final String NIGHT_MODE = "NIGHT_MODE";
    private boolean isNightModeEnabled = false;
    private static ModeGelap singleton = null;

    public static ModeGelap getInstance() {
        if(singleton == null)
        {
            singleton = new ModeGelap();
        }
        return singleton;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
        SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        this.isNightModeEnabled = mPrefs.getBoolean(NIGHT_MODE, false);
    }

    public boolean isNightModeEnabled() {
        return isNightModeEnabled;
    }

    public void setIsNightModeEnabled(boolean isNightModeEnabled) {
        this.isNightModeEnabled = isNightModeEnabled;
        SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
        editor.apply();
    }
}

Selanjutnya buatlah sebuah activity baru. Disni kita buat dengan nama activity_second dengan konteks java nya SecondAcivity. Untuk membuat activity baru, klik kanan pada package project atau MainActivity.java, kemudian New > Activity > Empty Activity. isikan nama nya lalu OK.  Untuk activity ini hanya akan ada sebuah komponen TextView untuk hiasan saja. Anda boleh saja untuk tidak melakukan apa-apa pada activity ini, karena guna nya nanti hanya memastikan bahwa tema pada activity ini mengikuti tema yang di pilih. Namun, jika Anda juga ingin mendekor nya, berikut isi dari activity_second.xml tutorial ini :

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="serif"
        android:textSize="20sp"
        android:text="@string/menu_makansiang"
        android:layout_marginTop="50dp"/>

</RelativeLayout>

Pada komponen TextView di atas, untuk teks nya sudah di ekstrak ke strings.xml. Berikut isi dari strings.xml dari tutorial ini :

<resources>
    <string name="app_name">proyekkeempat</string>

    <string name="menu_sarapan"><b>MENU SARAPAN</b>\n\nNasi Goreng\nNasi Rendang\nAyam Bakar\nAyam Goreng
    \nBebek Goreng\nSapi Hidup\nRendang Jengkol\nAyam Kampung + Jengkol Mentah\nIkan Salmon ala Eropa
    \nBeras 1 Kg\nDaging Anak Sapi\nTempe + Tahu\nKol di Rebus\nBandrek Dingin\nJahe Original
    \n</string>

    <string name="menu_makansiang"><b>MENU SANTAP SIANG</b>\n\nNasi Goreng\nNasi Rendang\nAyam Bakar\nAyam Goreng
    \nBebek Goreng\nSapi Hidup\nRendang Jengkol\nAyam Kampung + Jengkol Mentah\nIkan Salmon ala Eropa
    \nBeras 1 Kg\nDaging Anak Sapi\nTempe + Tahu\nKol di Rebus\nBandrek Dingin\nJahe Original
    \n</string>
</resources>

Kemudian beralih ke AndroidManifest.xml untuk mendaftarkan class dan activity yang sudah di buat. Untuk activity sendiri sebenarnya sudah terdaftarkan secara otomatis saat activity tersebut di buat. Berikut isi lengkap nya AndroidManifest dari project contoh ini sebagai panduan letak peletakkannya :


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.gwnbs.proyekkeempat">

    <application
        android:name=".ModeGelap"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="AllowBackup">
        <activity
            android:name=".SecondActivity"
            android:label="Menu Lunch"/>
        <activity
            android:name=".MainActivity"
            android:label="gwnbs.com | Dark Mode">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Selanjutnya menuju ke activity_main.xml. Pada layout ini terdapat 3 komponen yaitu : Sebuah tombol Switch untuk mengatur tema ke mode gelap atau mode terang, lalu sebuah TextView untuk dekorasi saja supaya layout tidak terlalu hampa. Isi teks dari komponen TextView ini juga sudah di ekstrak ke strings.xml, yang sudah di perlihatkan di atas. Lalu komponen terakhir sebuah Button yang akan mengarahkan ke activity_second / SecondActivity saat di klik. Isi selengkapnya pada activity_main.xml :

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

    <Switch
        android:id="@+id/switchDark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Enable Dark Mode "
        android:textSize="20sp"
        android:textStyle="bold"
        tools:ignore="UnusedAttribute" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="serif"
        android:textSize="20sp"
        android:text="@string/menu_sarapan"
        android:id="@+id/teks"
        android:layout_below="@id/switchDark"
        android:layout_marginTop="50dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/goLunch"
        android:text="Lihat Menu Siang"
        android:layout_centerHorizontal="true"
        android:onClick="gotoLunchMenu"
        android:layout_below="@id/teks"
        android:layout_marginTop="30dp"/>

</RelativeLayout>

Atribut onClick pada tombol di atas akan di tandai warna merah karena metode onClick belum di buat pada MainActivity. Abaikan saja dahulu, nanti akan di buat di akhir.
Tahap terakhir pada MainActivity.java, pertama-tama dengan membuat metode if else MODE_NIGHT_YES dan MODE_NIGHT_NO untuk class ModeGelap.java yang di buat tadi. Kodingan ini di letakkan pada metode onCreate tepat sebelum setContentView (R.layout.activity_main).

if (ModeGelap.getInstance().isNightModeEnabled()) {
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}

Kemudian membuat variabel untuk tombol Switch dan mendapatkan id nya yang ada pada activity_main.xml, lalu menyetel check / centang pada tombol Switch ke "false" dan juga menyetel check / centang nya  ke "true" saat mode gelap di hidupkan. Hal ini supaya saat aplikasi di restart / refresh, tanda centang pada tombol Switch tersebut tetap aktif saat mode gelap sudah hidup, dan tanda centang hilang saat mode gelap di matikan. Kodingan ini di letakkan di dalam metode onCreate di bawah setContentView :

Switch enableDark = findViewById(R.id.switchDark);
enableDark.setChecked(false);
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
    enableDark.setChecked(true);

Koding selanjutnya membuat listener check untuk tombol Switch tersebut. Untuk semua subkelas CompoundButton seperti ToggleButton, CheckBox dan Switch ini, di dalam listener check nya semua menggunakan metode "if else" saat di centang dan saat centangan nya di hilangkan.

Di dalam metode "if" ini, tentunya kodingan yang di buat adalah menghidupkan tema gelap, lalu beberapa kodingan untuk me refresh activity saat tema gelap di hidupkan. Dan sebaliknya kodingan untuk metode "else" mengembalikan ke mode terang dan juga me refresh activity. Peletakkan masih di dalam metode onCreate setelah kodingan terakhir :

enableDark.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            ModeGelap.getInstance().setIsNightModeEnabled(true);
            Intent intent = getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();
            startActivity(intent);
        } else {
            ModeGelap.getInstance().setIsNightModeEnabled(false);
            Intent intent = getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();
            startActivity(intent);
        }
    }
});

Terakhir, membuat metode onClick untuk tombol menuju ke SecondActivity yang di lewatkan tadi. Metode onClick ini di letakkan setelah metode onCreate. Sehingga kode keseluruhan pada MainActivity.java akan terlihat seperti di bawah ini :

package com.gwnbs.proyekkeempat;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.Switch;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (ModeGelap.getInstance().isNightModeEnabled()) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
        setContentView(R.layout.activity_main);

        Switch enableDark = findViewById(R.id.switchDark);
        enableDark.setChecked(false);
        if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
            enableDark.setChecked(true);

        enableDark.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    ModeGelap.getInstance().setIsNightModeEnabled(true);
                    Intent intent = getIntent();
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    finish();
                    startActivity(intent);
                } else {
                    ModeGelap.getInstance().setIsNightModeEnabled(false);
                    Intent intent = getIntent();
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    finish();
                    startActivity(intent);
                }
            }
        });
    }

    public void gotoLunchMenu(View view) {
        Intent lunch = new Intent(this, SecondActivity.class);
        startActivity(lunch);
    }
}

Berikut di bawah ini di sertakan video singkat hasil dari tutorial ini setelah proyek di running pada perangkat Android.  Terima kasih sudah membaca, jika ada pertanyaan bisa langsung di post di komentar atau melalui kontak form yang ada pada bilah samping kiri.



Comments

Post Terpopuler Sepanjang Masa

Cara Memasang Iklan Interstitial AdMob

Cara Memasang Iklan Banner AdMob di Android Studio

Aplikasi Pengingat Tugas (To Do Reminder) Android

Tutorial Menerapkan Animasi Lottie di Android Studio

Cara Merubah Package Name di Android Studio

Menampilkan Webview Pada Aplikasi di Android Studio

Cara Membuat Custom Icon Vector Asset di Android Studio