Android - 默认暗模式

Android - default dark mode

我想在我的应用中实现深色模式。默认情况下,我希望它一直被系统跟踪,所以在 Main Activity 中我放置了:

 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);

它工作正常,但如果用户想改变主意,select 我的应用程序菜单中的某些选项可以切换 off/on 暗模式,activity 正在重新启动并且应用程序仍在遵循系统规则。我该如何更改?

  @Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_color_mode) {
        if(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        else
            AppCompatDelegate.setDefaultNightMode(
                    AppCompatDelegate.MODE_NIGHT_YES);
        return true;
    }

Code responsible for option you mentioned, is within onCreate(). Mechanism that allows user to change mode is not within onCreate()

public class MainActivityextends AppCompatActivity {

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

当您明确更改深色模式时,Android 会重新创建 activity 并因此再次调用 onCreate

因此,在您更改深色模式后,您不会注意到有任何变化,因为系统调用 onCreate 时会再次调用 AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM

要实现此功能,您可以将一个值保存到 SharedPreference 中,可以在设置系统暗模式之前在 onCreate 中检查该值。

这可以是一个布尔值,当您想手动更改暗模式时可以切换它。

这是一个示例

public class MainActivityextends AppCompatActivity {

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

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        boolean isSystem = prefs.getBoolean("IS_SYSTEM", true);
        if (isSystem) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
        }       
        
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_color_mode) {
            if(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            else
                AppCompatDelegate.setDefaultNightMode(
                        AppCompatDelegate.MODE_NIGHT_YES);
                        
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            prefs.edit().putBoolean("IS_SYSTEM", false).apply();
            return true;
        }   
    
}

更新

that works perfect, but when I quit application and then launch again, default system mode is active although I've switched it. Is possible here to make it works in that way?

您可以使用另一个 SharedPreference 布尔值来永久保存

public class MainActivityextends AppCompatActivity {

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

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        boolean isSystem = prefs.getBoolean("IS_SYSTEM", true);
        boolean isNight = prefs.getBoolean("IS_NIGHT", false);

        if (isSystem) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
        } else if (isNight) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }   
        
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_color_mode) {

            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

            if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                prefs.edit().putBoolean("IS_NIGHT", false).apply();
    
            } else {
                AppCompatDelegate.setDefaultNightMode(
                        AppCompatDelegate.MODE_NIGHT_YES);
                prefs.edit().putBoolean("IS_NIGHT", true).apply();
            }

            prefs.edit().putBoolean("IS_SYSTEM", false).apply();
            return true;
        }   
    
}