【问题标题】:App freezes after PreferenceSwitch in settings Android Studio应用程序在设置 Android Studio 中的 PreferenceSwitch 后冻结
【发布时间】:2020-04-27 16:02:47
【问题描述】:

我在 Android Studio 中进行了设置活动,而不是手动进行。我想做一个在应用程序中应用暗模式的开关。问题是,当我单击开关时,没有移动动画,只有应用程序闪烁。当我返回主活动时,我看到主题已应用(我之前只尝试过主活动),但是当我尝试返回设置时,一切都被冻结了!什么都不能点击,完全没有反应。 这是我的 Java 代码:

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;

public class SettingsActivity extends AppCompatActivity {
    private SwitchPreference darkModeSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings, new SettingsFragment())
                .commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);

        }
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
            SwitchPreference darkModeSwitch = (SwitchPreference) findPreference("darkmode");
            assert darkModeSwitch != null;
            darkModeSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                    } else {
                        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                    }
                    return false;
                }
            });
        }
    }
}

这是 root_preferences.xml:

<PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">

<PreferenceCategory
    app:title="General">

    <SwitchPreference
        app:key="darkmode"
        app:title="Dark mode"/>
</PreferenceCategory>

这是应用主题后的Logcat:

avc: denied { getattr } for path="/proc/1" dev="proc" ino=3924 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=dir permissive=0

我想可能是因为我应用主题后没有再次启动activity,因为当我在main_activity中尝试暗模式时,有两行,在我的设置activity中无法放置,因为类是静态...请帮忙!

public void onClick(View v) {
                if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                } else {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                }
//These two
            finish();
            startActivity(new Intent(MainActivity.this, MainActivity.this.getClass()));
        }
    });

【问题讨论】:

    标签: java android xml preference android-dark-theme


    【解决方案1】:

    把这个放在你的preferences.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
        <SwitchPreferenceCompat
            app:defaultValue="false"
            app:key="@string/key_night_mode"
            app:summaryOff="@string/summary_night_mode_off"
            app:summaryOn="@string/summary_night_mode_on"
            app:title="@string/title_night_mode" />
    </PreferenceScreen>
    

    然后在您的SettingsFragment.java 中扩展PreferenceFragmentCompat 内的onCreatePreference() 方法:

        SwitchPreferenceCompat switchPreferenceCompat = findPreference(getString(R.string.key_night_mode));
    
        switchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        boolean isChecked = false;
                        if (newValue instanceof Boolean)
                            isChecked = (Boolean) newValue;
                        if (isChecked) {
                        //these lines so that the preference persists
    getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), true).apply();
                        //you do not need to finish and recreate activity
                        //it takes care of any such things that needs to be done  
                        //automatically
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                        } else {
                            getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.key_night_mode), false).apply();
                            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                        }
                        return true;
                    }
                });
    

    这些代码行对我有用。


    注意:

    1. AppTheme 应该从 Theme.AppCompat.DayNightTheme.MaterialComponents.DayNight 扩展,如果你想依赖于你的夜间主题平台。否则,您可以创建单独的 DayNight 主题,分别从 Theme.MaterialComponents.LightTheme.MaterialComponents 扩展(AppCompat 也有类似的主题集)。
    2. 应用程序每次启动时,都需要尊重用户的偏好,并相应地在用户设置的主题中启动。为此,您可以在MyApplication 类中检查首选项并设置主题,如下所示:

          SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
          boolean nightMode = sharedPreferences.getBoolean(getString(R.string.key_night_mode), false);
          if (nightMode)
              AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
          else {
              if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)
                  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
              else
                  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
          }
      

    【讨论】:

    • 非常感谢您在应用程序中设置用户偏好模式的提示!
    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2020-01-10
    • 2018-04-18
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多