첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.19MB

▶ Platforms/Android/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:allowBackup="true"
        android:icon="@android:mipmap/sym_def_app_icon"
        android:roundIcon="@mipmap/appicon_round"
        android:supportsRtl="true" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"   />
    <uses-permission android:name="android.permission.INTERNET"               />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"   />
</manifest>

 

728x90

 

▶ Platforms/iOS/info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>LSRequiresIPhoneOS</key>
        <true/>
        <key>UIDeviceFamily</key>
        <array>
            <integer>1</integer>
            <integer>2</integer>
        </array>
        <key>UIRequiredDeviceCapabilities</key>
        <array>
            <string>arm64</string>
        </array>
        <key>UISupportedInterfaceOrientations</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>UISupportedInterfaceOrientations~ipad</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationPortraitUpsideDown</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>XSAppIconAssets</key>
        <string>Assets.xcassets/appicon.appiconset</string>
        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
        <string>Need the location to display sunrise and sunset times</string>
    </dict>
</plist>

 

300x250

 

▶ Platforms/MacCatalyst/info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>UIDeviceFamily</key>
        <array>
            <integer>1</integer>
            <integer>2</integer>
        </array>
        <key>UIRequiredDeviceCapabilities</key>
        <array>
            <string>arm64</string>
        </array>
        <key>UISupportedInterfaceOrientations</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>UISupportedInterfaceOrientations~ipad</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationPortraitUpsideDown</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>XSAppIconAssets</key>
        <string>Assets.xcassets/appicon.appiconset</string>
        <key>NSLocationUsageDescription</key>
        <string>Need location to display sunrise and sunset info</string>
    </dict>
</plist>

 

반응형

 

▶ Platforms/Windows/Package.appxmanifest

<?xml version="1.0" encoding="utf-8"?>
<Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    IgnorableNamespaces="uap rescap">
    <Identity Publisher="CN=User Name" />
    <Properties>
        <PublisherDisplayName>User Name</PublisherDisplayName>
    </Properties>
    <Dependencies>
        <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
        <TargetDeviceFamily Name="Windows.Desktop"   MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
    </Dependencies>
    <Resources>
        <Resource Language="x-generate" />
    </Resources>
    <Applications>
        <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
            <uap:VisualElements />
        </Application>
    </Applications>
    <Capabilities>
        <rescap:Capability Name="runFullTrust" />
        <DeviceCapability Name="location" />
    </Capabilities>
</Package>

 

▶ DATA/MoonPhaseCalculator.cs

namespace TestProject
{
    /// <summary>
    /// 달 위상 계산기
    /// </summary>
    public static class MoonPhaseCalculator
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 위상 - Phase

        /// <summary>
        /// 위상
        /// </summary>
        public enum Phase
        {
            /// <summary>
            /// 삭(신월)
            /// </summary>
            New,

            /// <summary>
            /// 초승달
            /// </summary>
            WaxingCrescent,

            /// <summary>
            /// 상현달
            /// </summary>
            FirstQuarter,

            /// <summary>
            /// 소망월
            /// </summary>
            WaxingGibbous,

            /// <summary>
            /// 보름달
            /// </summary>
            Full,

            /// <summary>
            /// 기망월
            /// </summary>
            WaningGibbous,

            /// <summary>
            /// 하현달
            /// </summary>
            LastQuarter,

            /// <summary>
            /// 그믐달
            /// </summary>
            WaningCrescent,
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 달 공전 일수
        /// </summary>
        private static double _moonCycleDayLength = 29.530588853;

        /// <summary>
        /// 참조 신월 날짜
        /// </summary>
        private static DateTime _referenceNewMoonDate = new DateTime(2017, 11, 18);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 위상 구하기 - GetPhase(date)

        /// <summary>
        /// 위상 구하기
        /// </summary>
        /// <param name="date">날짜</param>
        /// <returns>위상</returns>
        public static Phase GetPhase(DateTime date)
        {
            return GetPhase(GetPhaseValue(date));
        }

        #endregion
        #region 위상 텍스트 구하기 - GetPhaseText(phase)

        /// <summary>
        /// 위상 텍스트 구하기
        /// </summary>
        /// <param name="phase">위상</param>
        /// <returns>위상 텍스트</returns>
        public static string GetPhaseText(Phase phase)
        {
            switch(phase)
            {
                case Phase.New            : return "삭(신월)";
                case Phase.WaxingCrescent : return "초승달";
                case Phase.FirstQuarter   : return "상현달";
                case Phase.WaxingGibbous  : return "소망월";
                case Phase.Full           : return "보름달";
                case Phase.WaningGibbous  : return "기망월";
                case Phase.LastQuarter    : return "하현달";
                case Phase.WaningCrescent : return "그믐달";
                default                   : return string.Empty;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Public

        #region 위상 값 구하기 - GetPhaseValue(date)

        /// <summary>
        /// 위상 값 구하기
        /// </summary>
        /// <param name="date">날짜</param>
        /// <returns>위상 값</returns>
        private static double GetPhaseValue(DateTime date)
        {
            double phaseValue = (date - _referenceNewMoonDate).TotalDays;

            return phaseValue % _moonCycleDayLength;
        }

        #endregion
        #region 위상 구하기 - GetPhase(phaseValue)

        /// <summary>
        /// 위상 구하기
        /// </summary>
        /// <param name="phaseValue">위상 값</param>
        /// <returns>위상</returns>
        private static Phase GetPhase(double phaseValue)
        {
            if(phaseValue < 1 ) return Phase.New;
            if(phaseValue < 7 ) return Phase.WaxingCrescent;
            if(phaseValue < 8 ) return Phase.FirstQuarter;
            if(phaseValue < 14) return Phase.WaxingGibbous;
            if(phaseValue < 15) return Phase.Full;
            if(phaseValue < 22) return Phase.WaningGibbous;
            if(phaseValue < 23) return Phase.LastQuarter;
            if(phaseValue < 29) return Phase.WaningCrescent;

            return Phase.New;
        }

        #endregion
    }
}

 

▶ DATA/ILocationService.cs

namespace TestProject
{
    /// <summary>
    /// 위치 서비스 인터페이스
    /// </summary>
    public interface ILocationService
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        #region 위치 구하기 - GetLocation()

        /// <summary>
        /// 위치 구하기
        /// </summary>
        /// <returns>(위도, 경도)</returns>
        Task<(double Latitude, double Longitude)> GetLocation();

        #endregion
    }
}

 

▶ DATA/LocationService.cs

namespace TestProject
{
    /// <summary>
    /// 위치 서비스
    /// </summary>
    public class LocationService : ILocationService
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 위치 구하기 - GetLocation()

        /// <summary>
        /// 위치 구하기
        /// </summary>
        /// <returns>(위도, 경로)</returns>
        public async Task<(double Latitude, double Longitude)> GetLocation()
        {
            double latitude  = 0d;
            double longitude = 0d;

            PermissionStatus status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

            if(status == PermissionStatus.Granted)
            {
                GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Default, TimeSpan.FromSeconds(10));

                Location location = await Geolocation.GetLocationAsync(request);

                latitude  = location.Latitude;
                longitude = location.Longitude;
            }

            return (latitude, longitude);
        }

        #endregion
    }
}

 

▶ DATA/SunriseService.cs

using System.Text.Json;

namespace TestProject
{
    /// <summary>
    /// 일출 서비스
    /// </summary>
    public class SunriseService
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Class
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 일출/일몰 결과 - SunriseSunsetResults

        /// <summary>
        /// 일출/일몰 결과
        /// </summary>
        private class SunriseSunsetResults
        {
            //////////////////////////////////////////////////////////////////////////////////////////////////// Property
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region 일출 - Sunrise

            /// <summary>
            /// 일출
            /// </summary>
            public string Sunrise { get; set; }

            #endregion
            #region 일몰 - Sunset

            /// <summary>
            /// 일몰
            /// </summary>
            public string Sunset { get; set; }

            #endregion
        }

        #endregion
        #region 일출/일몰 데이터 - SunriseSunsetData

        /// <summary>
        /// 일출/일몰 데이터
        /// </summary>
        private class SunriseSunsetData
        {
            //////////////////////////////////////////////////////////////////////////////////////////////////// Property
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region 결과 - Results

            /// <summary>
            /// 결과
            /// </summary>
            public SunriseSunsetResults Results { get; set; }

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field
 
        /// <summary>
        /// 서비스 URL
        /// </summary>
        private const string SERVICE_URL = "https://api.sunrise-sunset.org";

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 데이터 시간 구하기 - GetData(latitude, longitude)

        /// <summary>
        /// 데이터 구하기
        /// </summary>
        /// <param name="latitude">위도</param>
        /// <param name="longitude">경도</param>
        /// <returns>(일출 시간, 일몰 시간)</returns>
        public async Task<(DateTime SunriseTime, DateTime SunsetTime)> GetData(double latitude, double longitude)
        {
            string url = $"{SERVICE_URL}/json?lat={latitude}&lng={longitude}&date=today";

            HttpClient client = new HttpClient();

            client.DefaultRequestHeaders.Add("Accept", "application/json");

            string json = await client.GetStringAsync(url);

            JsonSerializerOptions options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

            SunriseSunsetData data = JsonSerializer.Deserialize<SunriseSunsetData>(json, options);

            return (DateTime.Parse(data.Results.Sunrise), DateTime.Parse(data.Results.Sunset));
        }

        #endregion
    }
}

 

▶ PAGE/MoonPhasePage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.MoonPhasePage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    Title="달 위상"
    BackgroundColor="Black">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="TextColor"         Value="White"  />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid>
        <Image
            Aspect="AspectFill"
            Source="starfield.png" />
        <Grid
            HorizontalOptions="Center"
            VerticalOptions="Center"
            RowSpacing="10"
            ColumnSpacing="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" />
                <ColumnDefinition Width="auto" />
                <ColumnDefinition Width="auto" />
                <ColumnDefinition Width="auto" />
            </Grid.ColumnDefinitions>
            <StackLayout Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4"
                Spacing="10">
                <Label x:Name="dateLabel"
                    FontAttributes="Bold"
                    Text="" />
                <Label x:Name="moonPhaseIconLabel"
                    FontSize="96"
                    Text="" />
                <Label x:Name="moonPhaseTextLabel"
                    FontAttributes="Bold"
                    Text="" />
            </StackLayout>
            <Label x:Name="phaseIconLabel1" Grid.Row="1" Grid.Column="0"
                FontSize="48" />
            <Label x:Name="phaseIconLabel2" Grid.Row="1" Grid.Column="1"
                FontSize="48" />
            <Label x:Name="phaseIconLabel3" Grid.Row="1" Grid.Column="2"
                FontSize="48" />
            <Label x:Name="phaseIconLabel4" Grid.Row="1" Grid.Column="3"
                FontSize="48" />
            <Label x:Name="phaseTextLabel1" Grid.Row="2" Grid.Column="0"
                FontSize="Medium"
                FontAttributes="Bold" />
            <Label x:Name="phaseTextLabel2" Grid.Row="2" Grid.Column="1"
                FontSize="Medium"
                FontAttributes="Bold" />
            <Label x:Name="phaseTextLabel3" Grid.Row="2" Grid.Column="2"
                FontSize="Medium"
                FontAttributes="Bold" />
            <Label x:Name="phaseTextLabel4" Grid.Row="2" Grid.Column="3"
                FontSize="Medium"
                FontAttributes="Bold" />
        </Grid>
    </Grid>
</ContentPage>

 

▶ PAGE/MoonPhasePage.xaml.cs

namespace TestProject;

/// <summary>
/// 달 위상 페이지
/// </summary>
public partial class MoonPhasePage : ContentPage
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Field
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Private

    #region Field

    /// <summary>
    /// 달 위상 딕셔너리
    /// </summary>
    private static Dictionary<MoonPhaseCalculator.Phase, string> _moonPhaseDictionary = new Dictionary<MoonPhaseCalculator.Phase, string>
    {
        { MoonPhaseCalculator.Phase.New           , "🌑" },
        { MoonPhaseCalculator.Phase.WaxingCrescent, "🌒" },
        { MoonPhaseCalculator.Phase.FirstQuarter  , "🌓" },
        { MoonPhaseCalculator.Phase.WaxingGibbous , "🌔" },
        { MoonPhaseCalculator.Phase.Full          , "🌕" },
        { MoonPhaseCalculator.Phase.WaningGibbous , "🌖" },
        { MoonPhaseCalculator.Phase.LastQuarter   , "🌗" },
        { MoonPhaseCalculator.Phase.WaningCrescent, "🌘" }
    };

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - MoonPhasePage()

    /// <summary>
    /// 생성자
    /// </summary>
    public MoonPhasePage()
    {
        InitializeComponent();

        MoonPhaseCalculator.Phase phase = MoonPhaseCalculator.GetPhase(DateTime.Now);

        this.dateLabel.Text          = DateTime.Today.ToString("yyyy/MM/dd");
        this.moonPhaseIconLabel.Text = _moonPhaseDictionary[phase];
        this.moonPhaseTextLabel.Text = MoonPhaseCalculator.GetPhaseText(phase);

        SetMoonPhaseLabels(this.phaseIconLabel1, this.phaseTextLabel1, 1);
        SetMoonPhaseLabels(this.phaseIconLabel2, this.phaseTextLabel2, 2);
        SetMoonPhaseLabels(this.phaseIconLabel3, this.phaseTextLabel3, 3);
        SetMoonPhaseLabels(this.phaseIconLabel4, this.phaseTextLabel4, 4);
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 달 위상 레이블 설정하기 - SetMoonPhaseLabels(phaseIconLabel, phaseTextLabel, dayOffset)

    /// <summary>
    /// 달 위상 레이블 설정하기
    /// </summary>
    /// <param name="phaseIconLabel">위상 아이콘 레이블</param>
    /// <param name="phaseTextLabel">위상 텍스트 레이블</param>
    /// <param name="dayOffset">날짜 오프셋</param>
    private void SetMoonPhaseLabels(Label phaseIconLabel, Label phaseTextLabel, int dayOffset)
    {
        MoonPhaseCalculator.Phase phase = MoonPhaseCalculator.GetPhase(DateTime.Now.AddDays(dayOffset));

        phaseIconLabel.Text = _moonPhaseDictionary[phase];
        phaseTextLabel.Text = DateTime.Now.AddDays(dayOffset).ToString("MM/dd");
    }

    #endregion
}

 

▶ PAGE/SunrisePage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.SunrisePage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    Title="일출">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout
        HorizontalOptions="Center"
        VerticalOptions="Center"
        Padding="10">
        <Label x:Name="dateLabel"
            WidthRequest="200"
            HorizontalTextAlignment="Center"
            FontAttributes="Bold" />
        <ActivityIndicator x:Name="activityIndicator"
            IsRunning="False"
            Color="Orange" />
        <Grid
            Padding="10"
            RowSpacing="10"
            ColumnSpacing="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0"
                FontSize="72"
                Text="🌅" />
            <Label Grid.Row="0" Grid.Column="1"
                FontSize="72"
                Text="☀️" />
            <Label Grid.Row="0" Grid.Column="2"
                FontSize="72"
                Text="🌇" />
            <Label Grid.Row="1" Grid.Column="0"
                FontAttributes="Bold"
                Text="일출" />
            <Label Grid.Row="1" Grid.Column="1"
                FontAttributes="Bold"
                Text="일광" />
            <Label Grid.Row="1" Grid.Column="2"
                FontAttributes="Bold"
                Text="일몰" />
            <Label x:Name="sunriseTimeLabel" Grid.Row="2" Grid.Column="0"
                WidthRequest="100"
                HorizontalTextAlignment="Center"
                FontAttributes="None" />
            <Label x:Name="daylightTimeLabel" Grid.Row="2" Grid.Column="1"
                WidthRequest="150"
                HorizontalTextAlignment="Center"
                FontAttributes="None" />
            <Label x:Name="sunsetTimeLabel" Grid.Row="2" Grid.Column="2"
                WidthRequest="100"
                HorizontalTextAlignment="Center"
                FontAttributes="None" />
        </Grid>
    </StackLayout>
</ContentPage>

 

▶ PAGE/SunrisePage.xaml.cs

namespace TestProject;

/// <summary>
/// 일출 페이지
/// </summary>
public partial class SunrisePage : ContentPage
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 위치 서비스 - LocationService

    /// <summary>
    /// 위치 서비스
    /// </summary>
    private ILocationService LocationService { get; set; }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - SunrisePage()

    /// <summary>
    /// 생성자
    /// </summary>
    public SunrisePage()
    {
        InitializeComponent();

        LocationService = new LocationService();
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Protected

    #region 표시시 처리하기 - OnAppearing()

    /// <summary>
    /// 표시시 처리하기
    /// </summary>
    protected override async void OnAppearing()
    {
        base.OnAppearing();

        this.activityIndicator.IsRunning = true;

        (DateTime SunriseTime, DateTime SunsetTime, TimeSpan DaylightTime) data = await GetData();

        this.dateLabel.Text         = DateTime.Today.ToString("yyyy-MM-dd");
        this.sunriseTimeLabel.Text  = data.SunriseTime.ToString("HH:mm");
        this.daylightTimeLabel.Text = $"{data.DaylightTime.Hours} 시간 {data.DaylightTime.Minutes} 분";
        this.sunsetTimeLabel.Text   = data.SunsetTime.ToString("HH:mm");

        this.activityIndicator.IsRunning = false;
    }

    #endregion

    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 데이터 구하기 - GetData()

    /// <summary>
    /// 데이터 구하기
    /// </summary>
    /// <returns>(일출 시간, 일몰 시간, 일광 시간)</returns>
    private async Task<(DateTime SunriseTime, DateTime SunsetTime, TimeSpan DaylightTime)> GetData()
    {
        (double Latitude, double Longitude) location = await LocationService.GetLocation();

        (DateTime SunriseTime, DateTime SunsetTime) data = await new SunriseService().GetData(location.Latitude, location.Longitude);

        DateTime sunriseTime  = data.SunriseTime.ToLocalTime();
        DateTime sunsetTime   = data.SunsetTime.ToLocalTime();
        TimeSpan daylightTime = sunsetTime.TimeOfDay - sunriseTime.TimeOfDay;

        return (sunriseTime, sunsetTime, daylightTime);
    }

    #endregion
}

 

▶ PAGE/AstronomicalBodyListPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.AstronomicalBodyListPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    Title="천체 목록">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Button">
                <Setter Property="BorderColor" Value="DarkGray" />
                <Setter Property="FontSize"    Value="100"      />
            </Style>
            <Style TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions"   Value="End"    />
                <Setter Property="Margin"            Value="5"      />
                <Setter Property="FontAttributes"    Value="Bold"   />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid
        Margin="10"
        RowDefinitions="*,*"
        ColumnDefinitions="*,*">
        <Button x:Name="earthButton" Grid.Row="0" Grid.Column="0"
            Margin="10"
            Text="🌎" />
        <Button x:Name="moonButton" Grid.Row="0" Grid.Column="1"
            Margin="10"
            Text="🌕" />
        <Button x:Name="sunButton" Grid.Row="1" Grid.Column="0"
            Margin="10"
            Text="☀️" />
        <Button x:Name="cometButton" Grid.Row="1" Grid.Column="1"
            Margin="10"
            Text="☄" />
    </Grid>
</ContentPage>

 

▶ PAGE/AstronomicalBodyListPage.xaml.cs

namespace TestProject;

/// <summary>
/// 천체 페이지
/// </summary>
public partial class AstronomicalBodyListPage : ContentPage
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - AstronomicalBodyListPage()

    /// <summary>
    /// 생성자
    /// </summary>
    public AstronomicalBodyListPage()
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ PAGE/AboutPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.AboutPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    Title="Contoso 천문학 정보">
    <StackLayout
        Padding="10"
        Spacing="5">
        <Label Text="버전 1.0.0" />
        <Label Text="일출/일몰 데이터 : https://sunrise-sunset.org/api" />
        <Label Text="아이콘 제공 : Font Awesome" />
    </StackLayout>
</ContentPage>

 

▶ PAGE/AboutPage.xaml.cs

namespace TestProject;

/// <summary>
/// ABOUT 페이지
/// </summary>
public partial class AboutPage : ContentPage
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - AboutPage()

    /// <summary>
    /// 생성자
    /// </summary>
    public AboutPage()
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ AppShell.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<Shell x:Class="TestProject.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:TestProject">
    <Shell.FlyoutHeader>
        <Grid
            HeightRequest="100"
            BackgroundColor="DarkSlateBlue">
            <Image Source="moon.png" />
        </Grid>
    </Shell.FlyoutHeader>
    <FlyoutItem
        Icon="moon.png"
        Title="천문">
        <ShellContent
            Icon="moon.png"
            Title="달"
            ContentTemplate="{DataTemplate local:MoonPhasePage}" />
        <ShellContent
            Icon="sun.png"
            Title="일광"
            ContentTemplate="{DataTemplate local:SunrisePage}" />
        <ShellContent
            Icon="comet.png"
            Title="천체"
            ContentTemplate="{DataTemplate local:AstronomicalBodyListPage}" />
    </FlyoutItem>
    <FlyoutItem
        Icon="question.png"
        Title="정보">
        <ShellContent ContentTemplate="{DataTemplate local:AboutPage}" />
    </FlyoutItem>
</Shell>

 

▶ AppShell.xaml.cs

namespace TestProject;

/// <summary>
/// 앱 셸
/// </summary>
public partial class AppShell : Shell
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - AppShell()

    /// <summary>
    /// 생성자
    /// </summary>
    public AppShell()
    {
        InitializeComponent();
    }

    #endregion
}

 

▶ App.xaml

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application x:Class="TestProject.App"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <Application.Resources>
        <Color x:Key="PrimaryColorKey">#512bd4</Color>
        <Color x:Key="WhiteColorKey">White</Color>
        <Color x:Key="BlackColorKey">Black</Color>
        <Color x:Key="LightGrayColorKey">#e5e5e1</Color>
        <Color x:Key="DarkGrayColorKey">#505050</Color>
        <Style TargetType="Page"
            ApplyToDerivedTypes="True">
            <Setter
                Property="Padding"
                Value="0" />
            <Setter
                Property="BackgroundColor"
                Value="{AppThemeBinding Light={StaticResource WhiteColorKey}, Dark={StaticResource BlackColorKey}}" />
        </Style>
        <Style TargetType="Shell" ApplyToDerivedTypes="True">
            <Setter
                Property="Shell.BackgroundColor"
                Value="{AppThemeBinding Light={StaticResource PrimaryColorKey}, Dark={StaticResource BlackColorKey}}" />
            <Setter
                Property="Shell.ForegroundColor"
                Value="{OnPlatform WinUI={StaticResource PrimaryColorKey}, Default={StaticResource WhiteColorKey}}" />
            <Setter
                Property="Shell.TitleColor"
                Value="{AppThemeBinding Light={StaticResource LightGrayColorKey}, Dark={StaticResource WhiteColorKey}}" />
            <Setter
                Property="Shell.DisabledColor"
                Value="{AppThemeBinding Light={StaticResource LightGrayColorKey}, Dark={StaticResource DarkGrayColorKey}}" />
            <Setter
                Property="Shell.UnselectedColor"
                Value="{AppThemeBinding Light={StaticResource LightGrayColorKey}, Dark={StaticResource LightGrayColorKey}}" />
            <Setter
                Property="Shell.NavBarHasShadow"
                Value="False" />
            <Setter
                Property="Shell.TabBarBackgroundColor"
                Value="{AppThemeBinding Light={StaticResource WhiteColorKey}, Dark={StaticResource BlackColorKey}}" />
            <Setter
                Property="Shell.TabBarForegroundColor"
                Value="{AppThemeBinding Light={StaticResource PrimaryColorKey}, Dark={StaticResource WhiteColorKey}}" />
            <Setter
                Property="Shell.TabBarTitleColor"
                Value="{AppThemeBinding Light={StaticResource PrimaryColorKey}, Dark={StaticResource WhiteColorKey}}" />
            <Setter
                Property="Shell.TabBarUnselectedColor"
                Value="{AppThemeBinding Light={StaticResource DarkGrayColorKey}, Dark={StaticResource LightGrayColorKey}}" />
        </Style>
        <Style TargetType="Label">
            <Setter
                Property="TextColor"
                Value="{AppThemeBinding Light={StaticResource BlackColorKey}, Dark={StaticResource WhiteColorKey}}" />
            <Setter
                Property="FontFamily"
                Value="OpenSansRegular" />
            <Setter
                Property="FontSize"
                Value="14" />
        </Style>
        <Style TargetType="Button">
            <Setter
                Property="TextColor"
                Value="{AppThemeBinding Light={StaticResource WhiteColorKey}, Dark={StaticResource PrimaryColorKey}}" />
            <Setter
                Property="BackgroundColor"
                Value="{AppThemeBinding Light={StaticResource PrimaryColorKey}, Dark={StaticResource WhiteColorKey}}" />
            <Setter
                Property="FontFamily"
                Value="OpenSansRegular"/>
            <Setter
                Property="FontSize"
                Value="14" />
            <Setter
                Property="CornerRadius"
                Value="8" />
            <Setter
                Property="Padding"
                Value="14,10" />
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="Disabled">
                            <VisualState.Setters>
                                <Setter
                                    Property="TextColor"
                                    Value="{AppThemeBinding Light={StaticResource DarkGrayColorKey}, Dark={StaticResource LightGrayColorKey}}" />
                                <Setter
                                    Property="BackgroundColor"
                                    Value="{AppThemeBinding Light={StaticResource LightGrayColorKey}, Dark={StaticResource DarkGrayColorKey}}" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
        <Style TargetType="ActivityIndicator">
            <Setter
                Property="Color"
                Value="{AppThemeBinding Light={StaticResource PrimaryColorKey}, Dark={StaticResource WhiteColorKey}}" />
        </Style>
    </Application.Resources>
</Application>

 

▶ App.xaml.cs

namespace TestProject;

/// <summary>
/// 앱
/// </summary>
public partial class App : Application
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - App()

    /// <summary>
    /// 생성자
    /// </summary>
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }

    #endregion
}

 

▶ MauiProgram.cs

namespace TestProject;

/// <summary>
/// MAUI 프로그램
/// </summary>
public static class MauiProgram
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Public

    #region MAUI 앱 생성하기 - CreateMauiApp()

    /// <summary>
    /// MAUI 앱 생성하기
    /// </summary>
    /// <returns>MAUI 앱</returns>
    public static MauiApp CreateMauiApp()
    {
        MauiAppBuilder builder = MauiApp.CreateBuilder();

        builder
            .UseMauiApp<App>()
            .ConfigureFonts
            (
                fontCollection =>
                {
                    fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" );
                    fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                }
            );

        return builder.Build();
    }

    #endregion
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요