Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Cross-Platform OS Theme APIs #9958

Merged
merged 23 commits into from Apr 3, 2020
Merged

Cross-Platform OS Theme APIs #9958

merged 23 commits into from Apr 3, 2020

Conversation

jfversluis
Copy link
Member

@jfversluis jfversluis commented Mar 13, 2020

Description of Change

Adds the cross-platform APIs to support different OS Themes

Background

See #9804 for the relevant APIs and how to use it. Because of timing I have removed the dependency on Essentials from this (see #9926) so we can get this merged in time for 4.6. After that, we can easily swap out this implementation for the Essentials one. By keeping naming and enum values, etc. the same this should be an easy task.

Issues Resolved

API Changes

Added:

  • public enum AppTheme { Unspecified, Light, Dark }
  • public class AppThemeColor
  • public class OnAppTheme
  • AppTheme Application.RequestedTheme { get; }
  • public event EventHandler Application.RequestedThemeChanged;
  • public void Application.OnRequestedThemeChanged(AppThemeChangedEventArgs args)
  • public class AppThemeChangedEventArgs
  • protected virtual void OnRequestedThemeChanged(AppTheme newValue)

Platforms Affected

  • Core/XAML (all platforms)
  • iOS
  • Android
  • UWP
  • MacOS
  • WPF
  • Tizen

Behavioral/Visual Changes

None

Before/After Screenshots

Not applicable

Testing Procedure

I have added a gallery page which shows (nearly) all ways to use this new functionality. Check if that works as expected. Whenever the values are used as a DynamicResource they should update whenever the theme is changed while the app is running. Check out the gallery page or, to take it a step further, download the NuGets and take it for a spin in your own (sample) app.

PR Checklist

  • Targets the correct branch
  • Tests are passing (or failures are unrelated)

@samhouts samhouts added this to In Review in v4.6.0 Mar 13, 2020
@jfversluis jfversluis added the blocker Issue blocks next stable release. Prioritize fixing and reviewing this issue. label Mar 16, 2020
@jsuarezruiz
Copy link
Contributor

I have done some tests. If you change the system theme, when initializing a page we initialize OnAppTheme and load the correct theme color. However, if we move the App to the background, change the theme and return to the App, the change will not be detected until navigating, etc.

xamarinforms-themes

Still missing to implement an event to detect change in appearance mode, right?. Is the PR in progress or are we going to divide the Spec into different PRs?.

@jsuarezruiz
Copy link
Contributor

The failed tests seem unrelated.

Xamarin.Forms.Core/AppThemeColor.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Core/AppThemeColor.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Core/AppThemeColor.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Platform.Android/Renderers/PageRenderer.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Platform.UAP/WindowsBasePlatformServices.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Platform.iOS/Forms.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Platform.iOS/Forms.cs Outdated Show resolved Hide resolved
Xamarin.Forms.Xaml/MarkupExtensions/OnAppThemeExtension.cs Outdated Show resolved Hide resolved
Copy link
Member

@StephaneDelcroix StephaneDelcroix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only reviewed the Core part, some minor remarks here and there

{
Unspecified,
Light,
Dark
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we sure we won't need to extend this list ? if so, we might want to use strings...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StephaneDelcroix Essentials defined it first in this way, so I think this was done to keep this in sync

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed follow the Essentials way for now. I'd like to think this is like the OS level theming and on top of that people can have their own custom theming, probably as an extension of this (naming will be a hell...). But if you implement your own theme as a user, you still might want to also follow the light and dark mode by the OS and show different colors based on that.


namespace Xamarin.Forms
{
public class AppThemeColor : BindableObject, IDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this definitely doesn't look like a BindableObject. It's never parented, so it probably never gets a BindingContext set...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I'm using bindable properties? Should I be using something different?


namespace Xamarin.Forms
{
public class OnAppTheme<T> : BindableObject, IDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a BO. look at OnPlatform, OnDevice

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, you might want a xaml markup language extension

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I'm using bindable properties? Should I be using something different? And there is an extension as well; https://github.com/xamarin/Xamarin.Forms/pull/9958/files#diff-c65a7e8e0eed508c58cd0802b61b2cb1

public void Reload()
{
foreach (var mr in MergedResources)
OnValuesChanged(mr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to avoid doing that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the latest changes it has at least changed to internal. I know it's not pretty and open to alternatives. But the problem is that the actual value doesn't really change. Depending on the theme the implicit operator will return a different color and that is why it's not picked up normally.

The only time this happens is when the theme changes on OS level and then a number of expensive operations already happen to redraw the whole screen already.

Copy link
Contributor

@PureWeen PureWeen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samhouts samhouts merged commit 529c8e9 into 4.6.0 Apr 3, 2020
v4.6.0 automation moved this from In Review to Done Apr 3, 2020
@samhouts samhouts deleted the implement-onapptheme branch April 3, 2020 21:47
@samhouts samhouts added this to the 4.6.0 milestone Apr 9, 2020
@samhouts samhouts added this to Done in Sprint 168 Apr 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a/darkmode a/Xaml </> API-change Heads-up to reviewers that this PR may contain an API change blocker Issue blocks next stable release. Prioritize fixing and reviewing this issue. ControlGallery Core p/Android p/gtk p/iOS 🍎 p/macOS p/Tizen p/UWP p/WPF roadmap
Projects
No open projects
Sprint 168
  
Done
v4.6.0
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

7 participants