Xamarin.Forms应用程序可以使用DynamicResource标记扩展在运行时动态响应样式更改。

此标记扩展类似于StaticResource标记扩展,两者都使用字典键从ResourceDictionary中获取值。 但是,在StaticResource标记扩展执行单个字典查找的同时,DynamicResource标记扩展维护与字典键的链接。 因此,如果替换了与键关联的值,则更改将应用于VisualElement。 这使得可以在Xamarin.Forms应用程序中实现运行时主题。

在Xamarin.Forms应用程序中实现运行时主题的过程如下:

  1. 创建一个xaml文件,继承ResourceDictionary,并在其中为每个主题定义资源
  2. 使用DynamicResource标记扩展在应用程序中使用主题资源
  3. 在应用程序的App.xaml文件中设置默认主题
  4. 添加代码以在运行时加载主题。

定义主题

创建xaml文件,主题定义为存储在ResourceDictionary中的资源对象的集合。

以下示例显示了示例应用程序中的LightTheme:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
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包含定义各自主题的Color资源,每个ResourceDictionary使用相同的键值。 有关资源字典的更多信息,请参见资源字典

注:每个ResourceDictionary都需要cs隐藏代码,该代码调用InitializeComponent方法,这是必需的,以便可以在运行时创建表示所选主题的CLR对象。

设置默认主题

应用程序需要默认主题,以便控件具有它们消耗的资源的值。 可以通过将主题的ResourceDictionary合并到App.xaml中定义的应用程序级ResourceDictionary来设置默认主题:

<Application xmlns="http://xamarin.com/schemas/2014/forms"
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://xamarin.com/schemas/2014/forms"
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>

这些样式在应用程序级 资源字典中定义(主题的xaml文件中),以便它们可以被多个页面使用。 每种样式都使用DynamicResource标记扩展来消耗主题资源。

这些样式随后被页面使用:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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=" • Cynical but not unfriendly."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Seven varieties of grimaces."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Doesn't laugh at your jokes."
Style="{StaticResource SmallLabelStyle}" />
</StackLayout>
...
</Grid>
</ScrollView>
</ContentPage>

直接使用主题资源时,应使用DynamicResource标记扩展来使用。 但是,当使用了使用DynamicResource标记扩展的样式时,应将其与StaticResource标记扩展一起使用。

在运行时加载主题

在运行时选择主题时,应用程序应:

  1. 从应用程序中删除当前主题。 通过清除应用程序级ResourceDictionary的MergedDictionaries属性来实现。
  2. 加载所选主题。 这是通过将所选主题的实例添加到应用程序级ResourceDictionary的MergedDictionaries属性中来实现的。

任何使用DynamicResource标记扩展设置属性的VisualElement对象都将应用新的主题值。 发生这种情况是因为DynamicResource标记扩展保留了到字典键的链接。 因此,当替换与键关联的值时,所做的更改将应用于VisualElement对象。

在示例应用程序中,通过包含Picker的模式页面选择主题。 以下代码显示了OnPickerSelectionChanged方法,该方法在选定主题更改时执行:

void OnPickerSelectionChanged(object sender, EventArgs e)
{
Picker picker = sender as Picker;
Theme theme = (Theme)picker.SelectedItem; ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
mergedDictionaries.Clear(); switch (theme)
{
case Theme.Dark:
mergedDictionaries.Add(new DarkTheme());
break;
case Theme.Light:
default:
mergedDictionaries.Add(new LightTheme());
break;
}
}
}

Xamarin.Forms之主题的更多相关文章

  1. Xamarin.Forms 简介

    An Introduction to Xamarin.Forms 来源:http://developer.xamarin.com/guides/cross-platform/xamarin-forms ...

  2. 张高兴的 Xamarin.Forms 开发笔记:Android 快捷方式 Shortcut 应用

    一.Shortcut 简介 Shortcut 是 Android 7.1 (API Level 25) 的新特性,类似于苹果的 3D Touch ,但并不是压力感应,只是一种长按菜单.Shortcut ...

  3. Xamarin.Forms之页面及导航

    参考链接: Xamarin. Forms 页面 Xamarin.Forms 导航 Xamarin.Forms 第04局:页面 Xamarin.Forms页面代表跨平台的移动应用程序屏幕. 下文描述的所 ...

  4. 【Xamarin.Forms 2】App基础知识与App启动

    系列目录 1.[Xamarin.Forms 1]App的创建与运行 引言 本篇文章将介绍Xamarin.Forms中 App 基础知识和 App的启动. 开发环境 Visual Studio 2019 ...

  5. xamarin.forms新建项目android编译错误

    vs2015 update3 新建的xamarin.forms项目中的android项目编译错误.提示缺少android_m2repository_r22.zip,96659D653BDE0FAEDB ...

  6. Xamarin.Forms 免费电子书

    Xamarin Evolve 正在举行,现在已经放出2本免费的Xamarin.Forms 免费电子书,据现场的同学说这两天还有Xamarin.Forms 重磅消息发布: Creating Mobile ...

  7. 老司机学新平台 - Xamarin Forms开发框架之MvvmCross插件精选

    在前两篇老司机学Xamarin系列中,简单介绍了Xamarin开发环境的搭建以及Prism和MvvmCross这两个开发框架.不同的框架,往往不仅仅使用不同的架构风格,同时社区活跃度不同,各种功能模块 ...

  8. 老司机学新平台 - Xamarin Forms开发框架二探 (Prism vs MvvmCross)

    在上一篇Xamarin开发环境及开发框架初探中,曾简单提到MvvmCross这个Xamarin下的开发框架.最近又评估了一些别的,发现老牌Mvvm框架Prism现在也支持Xamarin Forms了, ...

  9. 使用Xamarin.Forms平台开发移动应用指南

    下载书:链接: http://pan.baidu.com/s/1c29H9KG 密码: 7esm 注:捣鼓虚拟机把Hyper-V关闭,后来Xamarin搞挂了,所以暂停翻译. 第1章 Xamarin. ...

随机推荐

  1. B树和B+树的增/删结点(转)

    add by zhj: 算法其实不复杂,尤其是增加结点的算法,逻辑很简单,但有时自己想不到. 增加结点算法:首先,对于B树,没有重复结点,所以新插入的数据一定会落在叶结点上,或者说落在叶结点的所有父结 ...

  2. 详细的Hadoop的入门教程-单机模式 Standalone Operation

    一. 单机模式Standalone Operation 单机模式也叫本地模式,只适用于本地的开发调试,或快速安装体验hadoop,本地模式的安装比较简单,下载完hadoop安装包就可以直接运行. 1. ...

  3. Python面向对象之私有属性和私有方法

    01. 应用场景及定义方式 应用场景 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到 私有属性 就是 对象 不希望公开的 属性 私有方法 就是 对象  ...

  4. promiseall的使用场景

    在上图中点击诊断后下方的图标会一次进行数据请求,根据请求回来的数据显示正常异常,在请求数据完成期间再次点击诊断不触发事件 let p1 = new Promise((resolve, reject) ...

  5. 解决javaScript在不同时区new Date()显示值不同问题

    在日期格式化时遇到的问题,日期格式化方法在最下面 如果在中国时区    formatDate('2019-07-09')  结果是 ‘2019-07-09’ 如果 在夏威夷时区 utc-10:00 或 ...

  6. fatal: unable to connect to github.com npm install fail问题

    解决方法 git config --global url."https://".insteadOf git://

  7. Django下JWT的使用

    前言 JWT 是 json web token 的缩写, token的作用你应该已经了解,用于识别用户身份避免每次请求都需要验证 用来解决前后端分离时的用户身份验证 在传统的web项目中 我们会在fo ...

  8. 接触手机脚本编程------基于触动精灵的lua编程

    Auto.js好用多了,还不用root直接能用,我为什么学这个呢..... 最近因为学习需要开始接触一门新的脚本语言,我更深刻的发现了,语言只是一种工具,重要的是解决问题的思维,由于这次是需要我快速掌 ...

  9. KVM虚拟机被OOM killer

    一.线上环境的虚拟机被KVM物理机kill掉 Linux 内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于 ...

  10. 点击一个超链接,弹出固定大小的新窗口(js实现)

    1.最基本的弹出窗口代码 <SCRIPT LANGUAGE="javascript"> <!-- window.open ('page.html') --> ...