java - 应用程序完全关闭时如何在android中保存暗模式状态

标签 java android android-dark-theme android-darkmode

我有一个小问题。当我在我的应用程序中打开暗模式然后在 android 中完全关闭我的应用程序时,当我重新打开它时,它会返回到亮模式。我使用 AppCompatDelegate 来做到这一点。我有一个带有开关的设置 fragment ,可以打开或关闭暗模式,效果很好。我在那个 fragment 上有一个共享的开关偏好,它可以工作。唯一的问题是应用程序的其余部分在完全关闭后重新打开后不会停留在暗模式。有没有办法可以在关闭重新打开时保存然后恢复暗模式?

这是我的 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");
        }
    }

这是我的 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);
    }
    //------------------------------------------------------------------------
}

最佳答案

您应该在 ApplicationonCreate() 方法中设置它

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);
     }
    }
}

别忘了添加 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"

关于java - 应用程序完全关闭时如何在android中保存暗模式状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61310165/

相关文章:

java - 如何限制用户在swt文本框中输入某些字符

java - 如何将我的自定义相机应用程序设置为默认应用程序?

android - 使用深色主题时如何使 Android CardView 可见

Android ActionBar/Toolbar 颜色在浅色和深色主题中不同

java - Java中的最优路径(tsp)

java - 如何通过Java POI在excel中移动图表的位置

Java applets - 在你声明的地方初始化和实例化

Android如何重新启动我的应用程序以前运行的 Activity

android - Ml Kit 无法检测到护照 MRZ 代码?

flutter - 错误 : A value of type 'AppStateNotifier' can't be assigned to a variable of type 'Widget