How to make a dark mode setting

Viewed 719

I am new to android development and I am looking to make a dark mode setting in my application. For this I created a "preferences.xml" file which is displayed using a "SettingsActivity.java" file and a "SettingsFragment.java" file. I looked for a lot of solutions on the internet but none worked. Does anyone have a tutorial, example or solution? Thanks

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <ListPreference
            android:key="@string/key_app_theme"
            android:title="@string/app_theme"
            android:summary=""
            android:icon="@drawable/ic_app_theme"
            android:entries="@array/pref_app_theme_entries"
            android:entryValues="@array/pref_app_theme_values"
            android:dialogTitle="@string/app_theme"
            android:defaultValue="1"/>

</PreferenceScreen>

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <string-array name="pref_app_theme_entries">
        <item>@string/system</item>
        <item>@string/battery_saver</item>
        <item>@string/light</item>
        <item>@string/dark</item>
    </string-array>
    <string-array name="pref_app_theme_values">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
    </string-array>
    
</resources>

activity_settings.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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_settings"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    tools:context=".SettingsActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/activity_settings_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="4dp"
        android:background="@color/colorPrimaryDark"
        app:title="@string/settings"
        app:titleTextColor="@color/colorAccent" />

    <FrameLayout
        android:id="@+id/activity_settings_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/activity_settings_toolbar" />

</RelativeLayout>

SettingsActivity.java

public class SettingsActivity extends AppCompatActivity {

    private static Preference settings;

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

        if (findViewById(R.id.activity_settings_fragment_container) !=null) {
            if (savedInstanceState != null)
                return;

            getFragmentManager().beginTransaction().add(R.id.activity_settings_fragment_container, new SettingsFragment()).commit();
        }

        Toolbar toolbar = findViewById(R.id.activity_settings_toolbar);
        toolbar.setTitleTextAppearance(this, R.style.KaushanScriptRegular);
        toolbar.setNavigationIcon(R.drawable.ic_back);
        toolbar.setNavigationOnClickListener(view -> {
            Intent intent = new Intent(SettingsActivity.this, MainActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.swipe_right_enter, R.anim.swipe_right_exit);
        });
    }
}

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment {

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

        addPreferencesFromResource(R.xml.preferences);
}
2 Answers
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.night_mode) {
            // Get the night mode state of the app.
            int nightMode = AppCompatDelegate.getDefaultNightMode();
            //Set the theme mode for the restarted activity
            if (nightMode == AppCompatDelegate.MODE_NIGHT_YES) {
                AppCompatDelegate.setDefaultNightMode
                        (AppCompatDelegate.MODE_NIGHT_NO);
            } else {
                AppCompatDelegate.setDefaultNightMode
                        (AppCompatDelegate.MODE_NIGHT_YES);
            }
// Recreate activity for the theme change to take effect.
            recreate();

        }
        return super.onOptionsItemSelected(item);
    }

Also, you can go with Check Theme Style

Refer to this video for developing a Night Mode: Night/Dark Mode Tutorial

It's given in Kotlin but the translation into Java is simple enough. For listening to SharedPreferences:

int theme = Integer.valueOf(sharedPreferences.getString("theme", "1"));
switch (theme) {
    case 3 :
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        break;
    case 4 :
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        break;
    case 2 :
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
        break;
    default :
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);

(Assuming that the Preference key for your theme setting is "theme".) The rest of the code is in XML files so it is unaltered when Java is used instead of Kotlin.

Related