다음을 통해 공유


앱 테마

샘플을 찾아봅니다. 샘플 찾아보기

.NET 다중 플랫폼 앱 UI(.NET MAUI) 앱은 태그 확장을 사용하여 DynamicResource 런타임 시 스타일 변경에 동적으로 응답할 수 있습니다. 이 태그 확장은 태그 확장과 유사 StaticResource 합니다. 즉, 둘 다 사전 키를 사용하여 값을 ResourceDictionary가져옵니다. 그러나 태그 확장이 StaticResource 단일 사전 조회를 수행하는 동안 태그 확장은 DynamicResource 사전 키에 대한 링크를 유지 관리합니다. 따라서 키와 연결된 값을 바꾸면 변경 내용이 적용됩니다 VisualElement. 이렇게 하면 .NET MAUI 앱에서 런타임 테마를 구현할 수 있습니다.

.NET MAUI 앱에서 런타임 테마를 구현하는 프로세스는 다음과 같습니다.

  1. 에서 각 테마에 대한 리소스를 ResourceDictionary정의합니다. 자세한 내용은 테마 정의를 참조 하세요.
  2. 앱의 App.xaml 파일에서 기본 테마를 설정합니다. 자세한 내용은 기본 테마 설정을 참조 하세요.
  3. 태그 확장을 사용하여 앱에서 테마 리소스를 DynamicResource 사용합니다. 자세한 내용은 테마 리소스 사용을 참조 하세요.
  4. 런타임에 테마를 로드하는 코드를 추가합니다. 자세한 내용은 런타임에 테마 로드를 참조 하세요.

Important

앱이 런타임에 StaticResource 테마를 동적으로 변경할 필요가 없는 경우 태그 확장을 사용합니다. 앱이 실행되는 동안 테마 전환이 예상되는 경우 태그 확장을 사용하여 DynamicResource 런타임에 리소스를 업데이트할 수 있습니다.

다음 스크린샷은 밝은 테마를 사용하는 iOS 앱과 어두운 테마를 사용하는 Android 앱이 있는 테마 페이지를 보여줍니다.

테마 앱의 기본 페이지 스크린샷.

참고 항목

런타임에 테마를 변경하려면 XAML 또는 C# 스타일 정의를 사용해야 하며 CSS를 사용할 수 없습니다.

.NET MAUI에는 시스템 테마 변경에 응답하는 기능도 있습니다. 시스템 테마는 디바이스 구성에 따라 다양한 이유로 변경 될 수 있습니다. 여기에는 사용자가 명시적으로 변경하고, 하루 중 시간으로 인해 변경되고, 저조도와 같은 환경 요인으로 인해 변경되는 시스템 테마가 포함됩니다. 자세한 내용은 시스템 테마 변경에 대한 응답을 참조 하세요.

테마 정의

테마는 에 저장된 리소스 개체의 컬렉션으로 ResourceDictionary정의됩니다.

다음 예제에서는 밝은 테마에 대한 이름을 LightTheme보여줍니다ResourceDictionary.

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.LightTheme">
    <Color x:Key="PageBackgroundColor">White</Color>
    <Color x:Key="NavigationBarColor">WhiteSmoke</Color>
    <Color x:Key="PrimaryColor">WhiteSmoke</Color>
    <Color x:Key="SecondaryColor">Black</Color>
    <Color x:Key="PrimaryTextColor">Black</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">Gray</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

다음 예제에서는 다음과 같은 ResourceDictionary 어두운 테마에 대한 이름을 DarkTheme보여줍니다.

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.DarkTheme">
    <Color x:Key="PageBackgroundColor">Black</Color>
    <Color x:Key="NavigationBarColor">Teal</Color>
    <Color x:Key="PrimaryColor">Teal</Color>
    <Color x:Key="SecondaryColor">White</Color>
    <Color x:Key="PrimaryTextColor">White</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">WhiteSmoke</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

각각 ResourceDictionaryColor 동일한 키 값을 사용하는 각 테마를 ResourceDictionary 정의하는 리소스를 포함합니다. 리소스 사전에 대한 자세한 내용은 리소스 사전을 참조 하세요.

Important

메서드를 호출하는 각 ResourceDictionary파일에 대한 코드 숨김 InitializeComponent 파일이 필요합니다. 선택한 테마를 나타내는 CLR 개체를 런타임에 만들 수 있도록 이 작업이 필요합니다.

기본 테마 설정

앱에는 기본 테마가 필요하므로 컨트롤에 사용하는 리소스에 대한 값이 있어야 합니다. 기본 테마는 App.xaml에 정의된 앱 수준으로 ResourceDictionary 테마 ResourceDictionary 를 병합하여 설정할 수 있습니다.

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>
        <ResourceDictionary Source="Themes/LightTheme.xaml" />
    </Application.Resources>
</Application>

리소스 사전 병합에 대한 자세한 내용은 병합된 리소스 사전을 참조 하세요.

테마 리소스 사용

앱이 테마를 나타내는 리소스에 저장된 리소스를 ResourceDictionary 사용하려는 경우 태그 확장을 사용하여 사용해야 DynamicResource 합니다. 이렇게 하면 런타임에 다른 테마를 선택하면 새 테마의 값이 적용됩니다.

다음 예제에서는 앱의 모든 Label 개체에 적용할 수 있는 세 가지 스타일을 보여 줍니다.

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>

        <Style x:Key="LargeLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource SecondaryTextColor}" />
            <Setter Property="FontSize"
                    Value="30" />
        </Style>

        <Style x:Key="MediumLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource PrimaryTextColor}" />
            <Setter Property="FontSize"
                    Value="25" />
        </Style>

        <Style x:Key="SmallLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource TertiaryTextColor}" />
            <Setter Property="FontSize"
                    Value="15" />
        </Style>

    </Application.Resources>
</Application>

이러한 스타일은 여러 페이지에서 사용할 수 있도록 앱 수준 리소스 사전에 정의됩니다. 각 스타일은 태그 확장과 함께 테마 리소스를 DynamicResource 사용합니다.

그러면 이러한 스타일이 페이지에서 사용됩니다.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ThemingDemo"
             x:Class="ThemingDemo.UserSummaryPage"
             Title="User Summary"
             BackgroundColor="{DynamicResource PageBackgroundColor}">
    ...
    <ScrollView>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200" />
                <RowDefinition Height="120" />
                <RowDefinition Height="70" />
            </Grid.RowDefinitions>
            <Grid BackgroundColor="{DynamicResource PrimaryColor}">
                <Label Text="Face-Palm Monkey"
                       VerticalOptions="Center"
                       Margin="15"
                       Style="{StaticResource MediumLabelStyle}" />
                ...
            </Grid>
            <StackLayout Grid.Row="1"
                         Margin="10">
                <Label Text="This monkey reacts appropriately to ridiculous assertions and actions."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Cynical but not unfriendly."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Seven varieties of grimaces."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Doesn't laugh at your jokes."
                       Style="{StaticResource SmallLabelStyle}" />
            </StackLayout>
            ...
        </Grid>
    </ScrollView>
</ContentPage>

테마 리소스를 직접 사용하는 경우 태그 확장과 함께 DynamicResource 사용해야 합니다. 그러나 태그 확장을 사용하는 DynamicResource 스타일이 사용되는 경우 태그 확장과 함께 StaticResource 사용해야 합니다.

스타일 지정에 대한 자세한 내용은 XAML을 사용하는 스타일 앱을 참조하세요. 태그 확장에 DynamicResource 대한 자세한 내용은 동적 스타일을 참조 하세요.

런타임에 테마 로드

런타임에 테마를 선택하면 앱은 다음을 수행해야 합니다.

  1. 앱에서 현재 테마를 제거합니다. 이 작업은 앱 수준의 ResourceDictionary속성을 지워 MergedDictionaries 서 수행됩니다.
  2. 선택한 테마를 로드합니다. 이 작업은 선택한 테마의 인스턴스를 앱 수준의 ResourceDictionary속성에 MergedDictionaries 추가하여 수행됩니다.

태그 확장을 사용하여 속성을 DynamicResource 설정하는 모든 VisualElement 개체는 새 테마 값을 적용합니다. 이는 태그 확장이 DynamicResource 사전 키에 대한 링크를 유지 관리하기 때문에 발생합니다. 따라서 키와 연결된 값을 바꾸면 변경 내용이 개체에 VisualElement 적용됩니다.

샘플 애플리케이션에서는 테마가 포함된 모달 페이지를 통해 선택됩니다 Picker. 다음 코드는 선택한 테마가 OnPickerSelectionChanged 변경될 때 실행되는 메서드를 보여줍니다.

다음 예제에서는 현재 테마를 제거하고 새 테마를 로드하는 방법을 보여줍니다.

ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
    mergedDictionaries.Clear();
    mergedDictionaries.Add(new DarkTheme());
}