Setting android theme to follow system does not change to current system theme

浪尽此生 提交于 2020-06-17 10:08:32

问题


In the settings of my app i have it so that you are able to switch the theme off the app between Light, Dark and following the system. Switching between them is fine and i have that all setup however when switching to follow system from one of the other themes it does not change to the systems theme if the theme before was different to the system.

I am using this code to switch the theme:

        {
            Spinner spinner = (Spinner)sender;
            string selectedSpinnerItem = spinner.GetItemAtPosition(e.Position).ToString();
            string chosenTheme = prefs.GetString("theme", "Light");

            if (selectedSpinnerItem != chosenTheme)
            {
                switch (selectedSpinnerItem)
                {
                    case "Light":
                        ((AppCompatActivity)Activity).Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightNo);
                        prefs.Edit().PutString("theme", "Light").Commit();
                        break;
                    case "Dark":
                        ((AppCompatActivity)Activity).Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightYes);
                        prefs.Edit().PutString("theme", "Dark").Commit();
                        break;
                    case "System Preference":
                        ((AppCompatActivity)Activity).Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightFollowSystem);
                        prefs.Edit().PutString("theme", "System Preference").Commit();
                        break;
                }
            }
        }

https://imgur.com/a/NBDFMCs

This takes place in a fragment of my main activity.


回答1:


Do you change your theme to extend from one of the DayNight variants, and then call one method to enable the feature ?

For example:

<style name="MyTheme" parent="Theme.AppCompat.DayNight">

   .......
</style>

If you’re using Material Design Components (and I recommend you to do so), then you can also use the Theme.MaterialComponents.DayNight theme from their v1.1.0 release.

And you should know the two methods.

setDefaultNightMode

The method is static so you can call it at any time. The value you set is not persisted across process starts though, therefore you need to set it every time your app process is started. I recommend setting it in your application class (if you have one)

like so:

[Application]
class MyApplication:Application
{
    public MyApplication(IntPtr handle, JniHandleOwnership ownerShip) : base(handle, ownerShip)
    {
    }
    public override void OnCreate()
    {
        base.OnCreate();

        AppCompatDelegate.DefaultNightMode =
       AppCompatDelegate.ModeNightFollowSystem;
    }
}

setLocalNightMode

Setting DayNight for a single Activity.

You can override the default value in each component with a call to its AppCompatDelegate’s setLocalNightMode(). This is handy when you know that only some components should use the DayNight functionality, or for development so that you don’t have to sit and wait for night to fall to test your layout. Using this method in every Activity is now an anti-pattern, and you should move to using setDefaultNightMode() instead.

the more you could look here

Update:

I checked the source code and it seems that it miss the handling when the mode is ModeNightFollowSystem

public void setLocalNightMode(int mode) {
    switch(mode) {
    case -1:
    case 0:
    case 1:
    case 2:
        if (this.mLocalNightMode != mode) {
            this.mLocalNightMode = mode;
            if (this.mApplyDayNightCalled) {
                this.applyDayNight();
            }
        }
        break;
    default:
        Log.i("AppCompatDelegate", "setLocalNightMode() called with an unknown mode");
    }

if mLocalNightMode = -1 (ModeNightFollowSystem),and when we call Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightFollowSystem);(-1) it will go out.

So I find a workaround,get the Current night mode first,then set it directly

case "System Preference":
     UiModeManager uiManager = (UiModeManager)GetSystemService(UiModeService);
     int mode = (int)uiManager.NightMode;
     Delegate.SetLocalNightMode(mode);
     prefs.Edit().PutString("theme", "System Preference").Commit();
   break;


来源:https://stackoverflow.com/questions/61229441/setting-android-theme-to-follow-system-does-not-change-to-current-system-theme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!