IT’s Ha

[MAUI] 테마 관리 본문

.NET/MAUI

[MAUI] 테마 관리

Deleloper Ha 2023. 3. 27. 22:47
728x90
반응형

안녕하세요. 이번포스팅은 Maui를 통하여 테마를 관리하는 방법을 포스팅하려고합니다. 

1. 프로젝트 생성 

이번 프로젝트의 프로젝트 이름은 ThemesExample로 프로젝트를 생성하였습니다.

프로젝트 생성

2. Resources - Styles - Colors.xaml 열기

<!-- Theme 1 -->
<Color x:Key="OneThemePrimary">gray</Color>
<Color x:Key="OneThemeSecondary">black</Color>
<Color x:Key="OneThemeTertiary">white</Color>

<!-- Theme 2 -->
<Color x:Key="TwoThemePrimary">blue</Color>
<Color x:Key="TwoThemeSecondary">green</Color>
<Color x:Key="TwoThemeTertiary">yellow</Color>

Colors.xaml파일 아래에 해당 코드를 복사 하여 입력하시면 됩니다. 위의 코드는 테마별 색상의 값을 지정한 내용입니다. Primary라는 색상 값을 그대로 사용하고, 그 앞에 테마 이름을 붙여 나중에 앞에 이름을 가지고 불러와 사용하는 방식으로 처리 할 예정입니다. 

3. MainPage.xaml 수정

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemesExample.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">
            <Label
                Text="Hello, World!"
                SemanticProperties.HeadingLevel="Level1"
                FontSize="32"
                TextColor="{DynamicResource Primary}"
                HorizontalOptions="Center" />
            <Button
                x:Name="OneTheme"
                Text="Click me"
                SemanticProperties.Hint="Counts the number of times you click"
                Clicked="OneTheme_Clicked"
                BackgroundColor="{DynamicResource Secondary}"
                TextColor="{DynamicResource Tertiary}"
                HorizontalOptions="Center" />
            <Button
                x:Name="TwoTheme"
                Text="Click me"
                SemanticProperties.Hint="Counts the number of times you click"
                Clicked="TwoTheme_Clicked"
                BackgroundColor="{DynamicResource Secondary}"
                TextColor="{DynamicResource Tertiary}"
                HorizontalOptions="Center" />
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

위의 코드로 수정합니다. 라벨은 TextColor를 Primary로, BackgroundColor와 TextColor를 각각 Secondary와 Tetiary로 설정 하였습니다. 

4. MainPage.cs 수정 

public void SetThemes(string themeName) 
{
    Preferences.Set("Theme", themeName);
    ICollection<ResourceDictionary> mergedDictionary = Application.Current.Resources.MergedDictionaries;
    if(mergedDictionary != null)
    {
        foreach(ResourceDictionary dictionary in mergedDictionary)
        {
            var primaryColor = dictionary.TryGetValue(themeName + "Primary", out var primary);
            if (primaryColor)
                dictionary["Primary"] = primary;
            
            var secondaryColor = dictionary.TryGetValue(themeName + "Secondary", out var secondary);
            if (secondaryColor)
                dictionary["Secondary"] = secondary;
            
            var tertiaryColor = dictionary.TryGetValue(themeName + "Tertiary", out var tertiary);
            if (tertiaryColor)
                dictionary["tertiary"] = tertiary;
        }
    }
}

void OneTheme_Clicked(System.Object sender, System.EventArgs e)
{
    SetThemes("OneTheme");
}

void TwoTheme_Clicked(System.Object sender, System.EventArgs e)
{
    SetThemes("TwoTheme");
}

OneThemeClick 이벤트는 OneTheme로 변경이고, TwoThemeClick 이벤트는 TwoTheme로 변경입니다 . Preferences 기본 설정 값을 셋팅하고 가져오는 내용입니다. 그리고 해당 선택된 테마는 Theme이름과 뒤에 색상의 키를 조합하여 색상을 셋팅하는 로직으로 되어있습니다. 해당 디자인은 Primary 색상을 참조하고 있지만, 참조의 위치를 Theme Primary로 변경 하는 함수입니다. 

5.  App.cs 수정

namespace ThemesExample;

public partial class App : Application
{
	public App()
	{
		InitializeComponent();
		SetTheme();
		MainPage = new AppShell();
	}
	public void SetTheme()
	{
		string themeName = string.Empty;
		var isInit = Preferences.Get("FirstLoad", true);

		if(isInit)
		{
			var currentTheme = Application.Current.RequestedTheme;

			if(currentTheme == AppTheme.Dark)
			{
				themeName = "OneTheme";
			}
			else if(currentTheme == AppTheme.Light)
			{
                themeName = "TwoTheme";
            }
		}
		else
		{
			themeName = Preferences.Get("Theme", "OneTheme");
		}
		Preferences.Set("FirstLoad", false);

        ICollection<ResourceDictionary> mergedDictionary = Application.Current.Resources.MergedDictionaries;
        if (mergedDictionary != null)
        {
            foreach (ResourceDictionary dictionary in mergedDictionary)
            {
                var primaryColor = dictionary.TryGetValue(themeName + "Primary", out var primary);
                if (primaryColor)
                    dictionary["Primary"] = primary;
                var secondaryColor = dictionary.TryGetValue(themeName + "Secondary", out var secondary);
                if (secondaryColor)
                    dictionary["Secondary"] = secondary;
                var tertiaryColor = dictionary.TryGetValue(themeName + "Tertiary", out var tertiary);
                if (tertiaryColor)
                    dictionary["tertiary"] = tertiary;
            }
        }
    }
}

App.cs 수정은 저장한 셋팅의 테마가 시스템을 껏다 켜도 문제없이 동작하는 것을 적용하기 위해서 반영되어야합니다. 만약, 반영되지 않는다면 프로그램의 재시작에도 테마는 초기화가 됩니다. 

6. 결과

 

실행 결과

위와 같이 결과가 정상적으로 된 것을 확인 하실수 있습니다. 색상을 변경하여 프로젝트에 적용하셔서 사용하셔도 됩니다. 

이상으로 오늘 포스팅은 여기까지 입니다. 궁금하신 내용이나 잘못된 내용은 댓글이나 메일로 부탁드리겠습니다.

728x90
반응형

'.NET > MAUI' 카테고리의 다른 글

[MAUI] Font 추가  (0) 2023.03.25
Comments