Xamarin Forms - Apresentando os modos Dark e Light


Hoje veremos como usar o novo recurso dos modos Dark e Light.

Um novo recurso agora disponível a partir da versão 4.7 em aplicações Xamarin Forms é a capacidade de alterar o estilo do aplicativo entre os modos claro e escuro.

Este recurso permite que os usuários tenham ainda mais controle para gerenciar o tema de seus aplicativos usando a propriedade UserAppTheme.

Para poder usar recurso, a primeira coisa que devemos fazer é definir o indicador experimental para AppTheme_Experimental, que nos permite configurar o estilo da aplicação e ver a atualização em tempo real da interface em tempo de execução, graças ao AppThemeBinding.

Assim no arquivo App.xaml.cs inclua a linha de código:

public App()
{
   Device.SetFlags(new string[] { "AppTheme_Experimental" });
   InitializeComponent();
   MainPage = new MainPage();
}

Independentemente do tema que for usado no dispositivo, podemos configurar o tema do aplicativo. Por exemplo, se estivermos no modo claro, mas queremos que o aplicativo que estamos desenvolvendo esteja no modo escuro, podemos adicionar a seguinte linha de código:

Application.Current.UserAppTheme = OSAppTheme.Dark;

Aqui OSAppTheme é uma enumeração que suporta os valores :

Assim, implementar o modo escuro no Xamarin Forms é bem simples. A primeira coisa que precisamos saber é o AppThemeBinding. Esse é um tipo de vinculação que nos permite fornecer valores diferentes para uma propriedade, dependendo se o aplicativo está no modo claro ou escuro. Pode ser aplicado em quase todos os lugares; imagens, cores do texto, tamanho da fonte, texto etc.

Veja um exemplo usando a propriedade AppThemBinding em uma Label e em uma Image :

<ContentPage>
     <StackLayout Margin="20">
            <Label Text="Este texto é verde no modo light, e vermelho no modo dark."
                       TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
             <Image Source="{AppThemeBinding Light=lightlogo.png, Dark=darklogo.png}" />
       </StackLayout>
</ContentPage>

A seguir com as vinculações definidas podemos usar duas propriedades para obter e definir os diferentes temas.

Para obter o tema atual usamos : OSAppTheme currentTheme = Application.Current.RequestedTheme;

Para definir o tema atual usamos :  Application.Current.UserAppTheme = OSAppTheme.Dark;

Usando o modo Dark e Light

Crie um novo projeto Xamarin Forms usando o template Blank:

No arquivo App.xaml vamos definir os temas e recursos que iremos usar na aplicação :

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XF_DarkLight.App">
    <Application.Resources>

        <Color x:Key="TransparentColor">Transparent</Color>

        <!-- cores claras -->
        <Color x:Key="LightPageBackgroundColor">White</Color>
        <Color x:Key="LightNavigationBarColor">WhiteSmoke</Color>
        <Color x:Key="LightPrimaryColor">WhiteSmoke</Color>
        <Color x:Key="LightSecondaryColor">Black</Color>
        <Color x:Key="LightPrimaryTextColor">Black</Color>
        <Color x:Key="LightSecondaryTextColor">White</Color>
        <Color x:Key="LightTertiaryTextColor">Gray</Color>

        <!-- cores escuras -->
        <Color x:Key="DarkPageBackgroundColor">Black</Color>
        <Color x:Key="DarkNavigationBarColor">Teal</Color>
        <Color x:Key="DarkPrimaryColor">Teal</Color>
        <Color x:Key="DarkSecondaryColor">White</Color>
        <Color x:Key="DarkPrimaryTextColor">White</Color>
        <Color x:Key="DarkSecondaryTextColor">White</Color>
        <Color x:Key="DarkTertiaryTextColor">WhiteSmoke</Color>

        <Style TargetType="NavigationPage">
            <Setter Property="BarBackgroundColor"
            Value="{AppThemeBinding Light={StaticResource LightNavigationBarColor},
Dark={StaticResource DarkNavigationBarColor}}" />
            <Setter Property="BarTextColor"
                Value="{AppThemeBinding Light={StaticResource LightSecondaryColor},
Dark={StaticResource DarkSecondaryColor}}" />
        </Style>

        <Style x:Key="ButtonStyle"
               TargetType="Button">
            <Setter Property="BackgroundColor"
                    Value="{AppThemeBinding Light={StaticResource LightPrimaryColor},
Dark={StaticResource DarkPrimaryColor}}" />
            <Setter Property="TextColor"
                    Value="{AppThemeBinding Light={StaticResource LightSecondaryColor},
Dark={StaticResource DarkSecondaryColor}}" />
            <Setter Property="HeightRequest"
                    Value="45" />
            <Setter Property="WidthRequest"
                    Value="190" />
            <Setter Property="CornerRadius"
                    Value="18" />
        </Style>

        <Style x:Key="LargeLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
           Value="{AppThemeBinding Light={StaticResource LightSecondaryTextColor},
Dark={StaticResource DarkSecondaryTextColor}}" />
            <Setter Property="FontSize"
                    Value="30" />
        </Style>

        <Style x:Key="MediumLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                Value="{AppThemeBinding Light={StaticResource LightPrimaryTextColor},
Dark={StaticResource DarkPrimaryTextColor}}" />
            <Setter Property="FontSize"
                    Value="18" />
        </Style>

        <Style x:Key="SmallLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
               Value="{AppThemeBinding Light={StaticResource LightTertiaryTextColor},
Dark={StaticResource DarkTertiaryTextColor}}" />
            <Setter Property="FontSize"
                    Value="15" />
        </Style>
    </Application.Resources>
</Application>

Aqui você pode ficar à vontade para definir os temas e recursos a seu gosto.

Agora no arquivo MainPage.xaml.cs vamos definir a lógica para usar o modo claro ou escuro permitindo ao usuário selecionar o modo desejado:

using Xamarin.Forms;
namespace XF_DarkLight
{
    public partial class MainPage : ContentPage
    {
        private OSAppTheme currentTheme = Application.Current.RequestedTheme;
        public MainPage()
        {
            InitializeComponent();
        }
        public bool IsChecked { get; set; }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            DisplayAlert("Alert", "O tema atual é  : " + currentTheme, "OK");
            if (currentTheme == OSAppTheme.Light)
            {
                checkLight.IsChecked = true;
            }
            else
            {
                checkDark.IsChecked = true;
            }
        }
        private void OnCheckBoxLight_CheckedChanged(object sender, CheckedChangedEventArgs e)
        {
            if (checkLight.IsChecked)
            {
                Application.Current.UserAppTheme = OSAppTheme.Light;
                checkDark.IsChecked = false;
            }
        }
        private void OnCheckBoxDark_CheckedChanged(object sender, CheckedChangedEventArgs e)
        {
            if (checkDark.IsChecked)
            {
                Application.Current.UserAppTheme = OSAppTheme.Dark;
                checkLight.IsChecked = false;
            }
        }
    }
}

Para concluir inclua no arquivo MainPage.xaml o código onde vamos definir uma interface simples com uma imagem e na abertura iremos detectar qual o modo usado e permitir o usuário alterar o modo:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XF_DarkLight.MainPage">
    <Grid Padding="1" >
        <ScrollView Padding="4">
            <StackLayout>
                <StackLayout VerticalOptions="Center" HorizontalOptions="Start" Margin="10">
                    <Label Text="Configurações" FontAttributes="Bold" FontSize="Title"
                           Style="{StaticResource MediumLabelStyle}"  />
                </StackLayout>
                <StackLayout>
                    <StackLayout>
                        <Grid VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="0.25*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>

                            <CheckBox x:Name="checkLight" Grid.Row="1" Grid.Column="1" VerticalOptions="Center" 
                                      CheckedChanged="OnCheckBoxLight_CheckedChanged"/>

                            <Label Grid.Row="1" Grid.Column="2" Text="Light Theme" VerticalOptions="Center" 
                                   Style="{StaticResource MediumLabelStyle}" />
                            <CheckBox x:Name="checkDark" Grid.Row="2" Grid.Column="1" VerticalOptions="Center" 
                                      CheckedChanged="OnCheckBoxDark_CheckedChanged" />

                            <Label Grid.Row="2" Grid.Column="2" Text="Dark Theme" VerticalOptions="Center" 
                                   Style="{StaticResource MediumLabelStyle}" />
                        </Grid>
                        <Grid BackgroundColor="{AppThemeBinding Light={StaticResource LightPrimaryColor},
                            Dark={StaticResource DarkPrimaryColor}}">
                            <Frame Margin="10"
                       CornerRadius="50"
                       HeightRequest="150"
                       WidthRequest="150"
                       IsClippedToBounds="True"
                       HorizontalOptions="Center"
                       VerticalOptions="Center">
                                <Image Grid.Column="1" Margin="-40"  Source="maco.jpg" HeightRequest="100"  WidthRequest="100"/>
                            </Frame>
                        </Grid>
                    </StackLayout>
                </StackLayout>
            </StackLayout>
        </ScrollView>
    </Grid>
</ContentPage>

Executando o projeto usando o emulador Genymotion teremos o resultado a seguir:

Pegue o projeto aqui:  XF_DarkLight.zip  (sem as referências)

"E muitos dos que dormem no pó da terra ressuscitarão, uns para vida eterna, e outros para vergonha e desprezo eterno."
Daniel 12:2

Referências:


José Carlos Macoratti