AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.17k stars 2.18k forks source link

Android no longer reacts to system theme change #16241

Open kerams opened 2 months ago

kerams commented 2 months ago

Describe the bug

@emmauss

To Reproduce

https://github.com/kerams/theme

Pull down the status bar and change theme, notice the application theme changes accordingly. Repeat with version 11.2.999-cibuild0049782-alpha and observe application theme does not change.

Expected behavior

No response

Avalonia version

11.2.999-cibuild0049474-alpha, 11.2.999-cibuild0049782-alpha

OS

Android

emmauss commented 1 month ago

Android seems to have a weird behavior concerning theme "ownership". A simple app(native android in this case) that doesn't change theme dynamically will always follow System theme. In this case, if the app is handling uiMode configuration changes to detect theme, both Activity.OnConfigurationChanged and View.OnConfigurationChanged will be called with the new ui mode.

If the app sets their app theme with AppCompatDelegate.DefaultNightMode to NightModeYes/No, the system no longer manages theming for the app, and only Activity.OnConfigurationChanged will be called for the app to detect system theme change. In avalonia, we rely on View.OnConfigurationChanged to detect system theme change, but since we enforce ThemeVariant when the app launches, we no longer receive uiMode notifications through View.OnConfigurationChanged. We can listen to it on Activity level, but that wouldn't work when an avalonia view is embedded in an Activity we don't control.

As at now, we have 2 PlatformThemeVariants, Dark and Light. There is no Default or System variant that would reset the app theme to the system one. Android saves the last NightMode for the app and applies it when the Activity is created, unless the app is newly installed, the RequestedThemeVariant usually set in App.xaml will be ignored on Android 12. This is due to requesting the systems/app theme accents here; https://github.com/AvaloniaUI/Avalonia/blob/9c6a2c931021aaf8a86da8c55ebd21e0609d2c2a/src/Android/Avalonia.Android/AvaloniaView.cs#L34 which will also forward the saved NightMode to the app.

So the current issues are as follows;

  1. We aren't able to detect system theme changes once we set our own theme.
  2. We force our theme at launch, which we can't reset to system theme. We still need to ensure the theme set in App.xaml, but the Default variant has no PlatformThemeVariant version.
  3. We need to be able to get platform accent colors without overriding the theme requested in App.xaml.

@maxkatz6 any thoughts? We could add a Default/System PlatformThemeVariant to restore system theme.

maxkatz6 commented 1 month ago

@emmauss we don't have PlatformThemeVariant.Default/System, because framework explicitly expects a specific value from the OS to be reported from the platform settings API - https://github.com/AvaloniaUI/Avalonia/blob/9c6a2c931021aaf8a86da8c55ebd21e0609d2c2a/src/Avalonia.Base/Platform/PlatformColorValues.cs#L34.

void SetFrameThemeVariant(PlatformThemeVariant themeVariant) might need to be nullable. But IIRC iOS didn't had an option to reset theme variant, which is why I left it non-nullable. But I might have forgot something.

But also, ideally, if theme wasn't changed, we shouldn't override any system value.

kerams commented 1 month ago

There's also one more issue. When you remove ConfigChanges.UiMode from ActivityAttribute, the application just crashes on system theme change.

emmauss commented 1 month ago

There's also one more issue. When you remove ConfigChanges.UiMode from ActivityAttribute, the application just crashes on system theme change.

That's because of the activity being restarted because of an unhandled config change. We should handle it, but it seems to be broken