【问题标题】:How to use Light Theme in Xamarin Forms?如何在 Xamarin Forms 中使用 Light Theme?
【发布时间】:2020-08-14 14:10:39
【问题描述】:

我更新了visual studio,现在程序的主题和手机上的一样,手机上是暗的,我想让程序亮一点,请帮忙,我试过Application.Current.UserAppTheme = OSAppTheme.Light,但它不起作用

【问题讨论】:

    标签: c# xamarin xamarin.forms xamarin.android themes


    【解决方案1】:

    您可以使用AppThemeBinding 设置浅色主题或深色主题。

    从下面的链接下载源文件并进行一些更改。 https://docs.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/userinterface-systemthemesdemo/

    当您在手机上设置暗模式并希望程序变亮时,您可以更改 xaml,如下所示:

    更改: ContentPage BackgroundColor

     BackgroundColor="{AppThemeBinding Light={StaticResource LightPageBackgroundColor}, Dark={StaticResource DarkPageBackgroundColor}}">
    

    收件人:

     BackgroundColor="{AppThemeBinding Light={StaticResource DarkPageBackgroundColor}, Dark={StaticResource LightPageBackgroundColor}}">
    

    更改:网格背景颜色

     <Grid BackgroundColor="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}">
    

    收件人:

     <Grid BackgroundColor="{AppThemeBinding Light={StaticResource DarkPrimaryColor}, Dark={StaticResource LightPrimaryColor}}">
    

    【讨论】:

      【解决方案2】:

      动态更改属性

      第一步是将受主题更新影响的每个视图属性都替换为静态资源。 这样做,例如,当您将 DynamicBackgroundColor 从黑色设置为白色时,它将自动传播到引用此键的所有属性。

      让我们看看我们的 App.xaml:

      <Color x:Key="DarkSurface">#121212</Color>  
      <Color x:Key="LightSurface">#00FF0266</Color>
      
      ...
      
      <Style ApplyToDerivedTypes="True" TargetType="ContentPage">  
      <Setter Property="Padding">
          <Setter.Value>
              <OnPlatform x:TypeArguments="Thickness">
                  <On Platform="iOS">0, 20, 0, 0</On>
                  <On Platform="Android">0, 0, 0, 0</On>
              </OnPlatform>
          </Setter.Value>
      </Setter>
      <Setter Property="BackgroundColor" Value="{DynamicResource DynamicBackgroundColor}" />
      </Style>
      
      <Style ApplyToDerivedTypes="True" TargetType="NavigationPage">  
          <Setter Property="BarBackgroundColor" Value="{DynamicResource 
                                                         DynamicNavigationBarColor}" />
          <Setter Property="BarTextColor" Value="{DynamicResource DynamicBarTextColor}" />
      </Style>  
      

      我们可以看到 DynamicResource 也适用于样式...

      DynamicResource 值的问题是您不会像经典的 StaticResource 那样在您的样式中定义它。 例如,DynamicBackgroundColor 没有在 xaml 中的任何地方定义,您可以将它们视为等待分配的引用。

      您可以像这样在代码中动态分配它们(之后我们将看到 SetDynamicResource 实现):

      // Dark Mode
      SetDynamicResource(DynamicBackgroundColor, "DarkSurface");
      
      // Ligh Mode
      SetDynamicResource(DynamicBackgroundColor, "LightSurface"); 
      

      在明暗模式之间切换

      在我的傻应用中!底部栏我有一个带有切换主题图标的 TabButton,单击它将调用 SetDarkMode() 或 SetLightMode():

      namespace SillyCompany.Mobile.Practices.Presentation.Views{
         public static class ResourcesHelper{
              public const string DynamicPrimaryTextColor = nameof(DynamicPrimaryTextColor);
              public const string DynamicSecondaryTextColor = nameof(DynamicSecondaryTextColor);
      
              public const string DynamicNavigationBarColor = nameof(DynamicNavigationBarColor);
              public const string DynamicBackgroundColor = nameof(DynamicBackgroundColor);
              public const string DynamicBarTextColor = nameof(DynamicBarTextColor);
      
              public const string DynamicTopShadow = nameof(DynamicTopShadow);
              public const string DynamicBottomShadow = nameof(DynamicBottomShadow);
      
              public const string DynamicHasShadow = nameof(DynamicHasShadow);
      
              public const string Elevation4dpColor = nameof(Elevation4dpColor);
      
              ...
      
              public static void SetDynamicResource(string targetResourceName, string sourceResourceName)
          {
              if (!Application.Current.Resources.TryGetValue(sourceResourceName, out var value))
              {
                  throw new InvalidOperationException($"key {sourceResourceName} not found in the resource dictionary");
              }
      
                Application.Current.Resources[targetResourceName] = value;
            }
      
            public static void SetDynamicResource<T>(string targetResourceName, T value)
            {
                Application.Current.Resources[targetResourceName] = value;
            }
      
            public static void SetDarkMode()
            {
                 MaterialFrame.ChangeGlobalTheme(MaterialFrame.Theme.Dark);
                 SetDynamicResource(DynamicNavigationBarColor, "DarkElevation2dp");
                 SetDynamicResource(DynamicBarTextColor, "TextPrimaryDarkColor");
      
                 SetDynamicResource(DynamicTopShadow, ShadowType.None);
                 SetDynamicResource(DynamicBottomShadow, ShadowType.None);
                 SetDynamicResource(DynamicHasShadow, false);
      
                 SetDynamicResource(DynamicPrimaryTextColor, "TextPrimaryDarkColor");
                 SetDynamicResource(DynamicSecondaryTextColor, "TextSecondaryDarkColor");
      
                 SetDynamicResource(DynamicBackgroundColor, "DarkSurface");
      
                 SetDynamicResource(Elevation4dpColor, "DarkElevation4dp");
             }
      
             public static void SetLightMode(){
                 MaterialFrame.ChangeGlobalTheme(MaterialFrame.Theme.Light);
                 SetDynamicResource(DynamicNavigationBarColor, "Accent");
                 SetDynamicResource(DynamicBarTextColor, "TextPrimaryDarkColor");
      
                 SetDynamicResource(DynamicTopShadow, ShadowType.Top);
                 SetDynamicResource(DynamicBottomShadow, ShadowType.Bottom);
                 SetDynamicResource(DynamicHasShadow, true);
      
                 SetDynamicResource(DynamicPrimaryTextColor, "TextPrimaryLightColor");
                 SetDynamicResource(DynamicSecondaryTextColor, "TextSecondaryLightColor");
      
                 SetDynamicResource(DynamicBackgroundColor, "LightSurface");
      
                 SetDynamicResource(Elevation4dpColor, "OnSurfaceColor");
              }
         }
      }
      

      你可以看到我不仅在改变颜色,而且在暗模式下禁用阴影,因为暗模式本质上是平坦的。

      示例:SillyBottomTabsPage.cs

      <tb:Toolbar x:Name="Toolbar"  
              Title="Silly App!"
              BackgroundColor="{DynamicResource DynamicNavigationBarColor}"
              ForegroundColor="White"
              HasShadow="{DynamicResource DynamicHasShadow}"
              Subtitle="The Official sample app for the Sharpnado's components" />
      
      ...
      
      <tabs:TabHostView   x:Name="TabHost"  
                      Grid.Row="2"
                      BackgroundColor="{DynamicResource Elevation4dpColor}"
                      ShadowType="{DynamicResource DynamicTopShadow}"
                      TabType="Fixed"
                      SelectedIndex="{Binding Source={x:Reference Switcher}, 
      Path=SelectedIndex, Mode=TwoWay}">
      
      <tabs:TabButton x:Name="TabButton"
                      IsVisible="True"
                      ButtonBackgroundColor="{StaticResource Accent}"
                      ButtonCircleSize="60"
                      ButtonPadding="15"
                      IconImageSource="theme_96.png"
                      Scale="1.3"
                      TranslationY="-10"
                      Clicked="TabButtonOnClicked" />
      
      ...
      

      过渡 现在让我们看看我们的过渡代码:

      SillyBottomTabsPage.xaml.cs

      private void TabButtonOnClicked(object sender, EventArgs e){
          TaskMonitor.Create(AnimateTabButton);
      }
      
      private void ApplyTheme(){
      
         if (_currentTheme == Theme.Light) {
              ResourcesHelper.SetLightMode();
              return;
         }
      
         ResourcesHelper.SetDarkMode();
      }
      
      private async Task AnimateTabButton(){
      
          double sourceScale = TabButton.Scale;
          Color sourceColor = TabButton.ButtonBackgroundColor;
          Color targetColor = _currentTheme == Theme.Light
          ? ResourcesHelper.GetResourceColor("DarkSurface")
          : Color.White;
      
          // Bounce then remove icon from button,
          await TabButton.ScaleTo(3);
          await TabButton.ScaleTo(sourceScale);
          TabButton.IconImageSource = null;
      
          // Ballon inflation
          var bigScaleTask = TabButton.ScaleTo(30, length: 500);
          // Change color to target dark/light mode
          var colorChangeTask = TabButton.ColorTo(
          sourceColor,
          targetColor,
          callback: c => TabButton.ButtonBackgroundColor = c,
          length: 500);
      
          // run animation at the same time
          await Task.WhenAll(bigScaleTask, colorChangeTask);
      
          _currentTheme = _currentTheme == Theme.Light ? Theme.Dark : Theme.Light;
          ApplyTheme();
      
          // reverse inflation and color animation to accent color
          var reverseBigScaleTask = TabButton.ScaleTo(sourceScale, length: 500);
          var reverseColorChangeTask = TabButton.ColorTo(
          targetColor,
          sourceColor,
          c => TabButton.ButtonBackgroundColor = c,
          length: 500);
      
          await Task.WhenAll(reverseBigScaleTask, reverseColorChangeTask);
      
          // icon is back
          TabButton.IconImageSource = "theme_96.png";
      }
      

      【讨论】:

      • 我想关闭深色主题,只使用浅色,怎么做?
      • 如何获得_currentTheme?
      猜你喜欢
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      相关资源
      最近更新 更多