MAUI에 테마 적용

.NET MAUI에서 어느사이 부터 시스템 테마가 잘 적용되어 있습니다.

직접 Light 또는 Dark 테마를 적용하려면 어떻게 해야 할까요? 다음과 같이 할 수 있습니다.

Application.Current.UserAppTheme = AppTheme.Light; // 또는 AppTheme.Dark

Application의 UserAppTheme 속성은 XAML에서 값에 AppThemeBinding을 적용했을 경우 테마의 변경에 맞게 일괄 변경해 줍니다. MAUI 기본 프로젝트 템플릿에서 Resources/Styles.xaml을 살펴보면,

...
    <Style TargetType="Border">
        <Setter Property="Stroke" Value="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}" />
        <Setter Property="StrokeShape" Value="Rectangle" />
        <Setter Property="StrokeThickness" Value="1" />
    </Style>
...

이런 식으로 테마 바인딩이 지정되어 있는 것을 확인할 수 있는데요, 라디오 버튼을 통해 테마를 선택할 수 있도록 약간 수정해봅시다.

| MainPage.xaml

       <VerticalStackLayout Padding="30" Spacing="25">
            <HorizontalStackLayout
                HorizontalOptions="End"
                IsVisible="true"
                Spacing="8">
                <Label Text="Theme" VerticalTextAlignment="Center" />
                <RadioButton
                    x:Name="lightThemeRadioButton"
                    CheckedChanged="lightThemeRadioButton_CheckedChanged"
                    Content="Light"
                    GroupName="theme"
                    MinimumWidthRequest="80" />
                <RadioButton
                    x:Name="darkThemeRadioButton"
                    CheckedChanged="darkThemeRadioButton_CheckedChanged"
                    Content="Dark"
                    GroupName="theme"
                    MinimumWidthRequest="80" />
            </HorizontalStackLayout>
...

| MainPage.xaml.cs

...
	public MainPage()
	{
		InitializeComponent();

		var theme = Application.Current.RequestedTheme;
		if (theme is AppTheme.Light)
			lightThemeRadioButton.IsChecked = true;
		else if (theme is AppTheme.Dark)
			darkThemeRadioButton.IsChecked = true;
	}

	private void lightThemeRadioButton_CheckedChanged(object sender, CheckedChangedEventArgs e)
	{
		Application.Current.UserAppTheme = AppTheme.Light;
	}

	private void darkThemeRadioButton_CheckedChanged(object sender, CheckedChangedEventArgs e)
	{
		Application.Current.UserAppTheme = AppTheme.Dark;
	}
...

실행해보면,

Light 라디오 버튼을 선택하면,

이상하군요… 분명히 Styles.xaml

...
    <Style ApplyToDerivedTypes="True" TargetType="Page">
        <Setter Property="Padding" Value="0" />
        <Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
    </Style>
...

페이지 관련 테마 바인딩이 적용되어 있는데도 불구하고 페이지 배경색이 변경되지 않습니다.

윈도우 머신으로 타겟을 변경해서, 실행한 후 테마를 바꾸면

image

이번에는 Shell도 테마가 적용되지 않습니다. 분명히 Styles.xaml에 ,

...
    <Style x:Key="BaseStyle" TargetType="Element">
        <Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
        <Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
        <Setter Property="Shell.TitleColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
        <Setter Property="Shell.DisabledColor" Value="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}" />
        <Setter Property="Shell.UnselectedColor" Value="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}" />
        <Setter Property="Shell.NavBarHasShadow" Value="False" />
        <Setter Property="Shell.TabBarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
        <Setter Property="Shell.TabBarForegroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
        <Setter Property="Shell.TabBarTitleColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
        <Setter Property="Shell.TabBarUnselectedColor" Value="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}" />
    </Style>
    <Style
        ApplyToDerivedTypes="True"
        BasedOn="{StaticResource BaseStyle}"
        TargetType="ShellItem" />
...

Shell관련 테마 바인딩이 적용되어 있는데도 불구하고 말이죠.
이것은 오동작으로 보이며 정식 릴리즈에는 수정될 것으로 보입니다.

그리고 한가지 더 문제가 있는데, 테마 바인딩을 별도로 지정하지 않으면 기본 적용된 테마를 코드로 변경할 수 없다는 점입니다. 이것 또한 정식 릴리즈에는 수정되어야 할 것 같네요.

좋아요 2

App.xaml.cs에,

	public App()
	{
		InitializeComponent();

		Application.Current.UserAppTheme = AppTheme.Light;

		MainPage = new AppShell();
	}

테마를 지정하면 정상적으로 앱 테마가 적용됩니다.

하지만 윈도 머신에서는 여전히 Shell은 적용이 되지 않네요.

좋아요 3