Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save dark mode state in android when the app is completely closed

I have a little problem. When I turn on dark mode in my app and then close my app completely in android, when I reopen it, it returns to light mode. I use AppCompatDelegate to do this. I have a settings fragment with a switch to turn on or off dark mode and it works well. I have a shared preferences on that fragment for the switch and it works. The only problem is that the rest of the application doesn't stay in dark mode after being completely closed the reopened after. Is there a way I can save and then restore the dark mode when I close the reopen it?

Here's my code for MainActivity:

package com.barzalou.lpapineau.test;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import com.barzalou.lpapineau.test.ui.CheckedChangeCallback;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class MainActivity extends AppCompatActivity implements CheckedChangeCallback {

    private AppBarConfiguration mAppBarConfiguration;

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

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
            R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow, R.id.nav_maps)
            .setDrawerLayout(drawer)
            .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_exit) {
            finish();
            System.exit(0);
        }
        return false;
    }

    public void onCheckedChange(boolean isChecked) {
        if (isChecked) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            Log.d("Dark Mode Switch State", "On");
        }
        else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            Log.d("Dark Mode Switch State", "Off");
        }
    }

Here's my code for SettingsFragment:

package com.barzalou.lpapineau.test.ui.settings;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.barzalou.lpapineau.test.R;
import com.barzalou.lpapineau.test.ui.CheckedChangeCallback;
import android.content.Context;

import static android.content.Context.MODE_PRIVATE;

public class SettingsFragment extends Fragment {

    private SettingsViewModel settingsViewModel;
    private static Switch DarkMode;
    private boolean SwitchOnOff;
    private CheckedChangeCallback callback = null;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        settingsViewModel = ViewModelProviders.of(this).get(SettingsViewModel.class);
        View root = inflater.inflate(R.layout.fragment_settings, container, false);
        final TextView textView = root.findViewById(R.id.text_settings);
        settingsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        return root;
    }

    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        DarkMode = (Switch) getView().findViewById(R.id.DarkModeSwitch);

        DarkMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                callback.onCheckedChange(isChecked);
            }
        });
    }

    public void onAttach(final Activity activity) {
        super.onAttach(activity);
        if (activity instanceof CheckedChangeCallback) {
            this.callback = (CheckedChangeCallback) activity;
        }
    }

    public void onDetach() {
        super.onDetach();
        callback = null;
    }

    //Save and Restore Switch, Buttons, Textboxs, etc -----------------------
    @Override
    public void onStop() {
        super.onStop();
        try {
            saveData();
            Log.d("Data Save", "Data was saved");
        } catch (Exception e) {
            Log.d("Data Save", "Data could not be saved");
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        try {
            loadData();
            updateViews();
            Log.d("Data Restore", "Data was restored");
        } catch (Exception e) {
           Log.d("Data Restore", "Data was not able to get restored");
        }
    }
    //------------------------------------------------------------------------



    // Save data, load data and update views functions -----------------------
    public void saveData() {
        SharedPreferences sharedPreferences = getContext().getSharedPreferences("SharedPrefs", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        // Add other Switches, Buttons, Texboxes, etc to save
        editor.putBoolean("SwitchState", DarkMode.isChecked());
        // Example: editor.putString("String1", textview.getText().toString());

        //---------------------------------------------------

        editor.apply();
    }

    public void loadData() {
        SharedPreferences sharedPreferences = getContext().getSharedPreferences("SharedPrefs", MODE_PRIVATE);
        SwitchOnOff = sharedPreferences.getBoolean("SwitchState", true); //Change true to false to make the switch on by default
    }

    public void updateViews() {
        DarkMode.setChecked(SwitchOnOff);
    }
    //------------------------------------------------------------------------
}
like image 750
Celoufran Avatar asked Nov 07 '25 09:11

Celoufran


1 Answers

You should set it in Application's onCreate() method

class MyApp : Application() {

    @Override
    public void onCreate() {
        super.onCreate();
        boolean isNightMode = sharedPreferences.getBoolean("SwitchState", true);
        if (isNightMode) {
          AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
       AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
     }
    }
}

Do not forget to add AndroidManifest

<application
    android:name=".MyApp"
    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"
like image 69
ysfcyln Avatar answered Nov 10 '25 00:11

ysfcyln



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!