zoukankan      html  css  js  c++  java
  • 博客园客户端(Universal App)开发随笔 -- 样式管理与夜间模式

    以今天的眼光来看,一个好应用首先是要有好的用户体验。而好的用户体验最直观的就来自于用户界面。好的用户界面则需要好的设计,更需要好的实现。今天我们就向大家分享一下我们在使用Xaml实现界面设计上的一点心得。

    样式管理

    我们拿到的设计,大多是一张红线图,布满了距离,字号,色号,事无巨细的量化了我们的用户界面。如果我们就这样把各种属性照搬到上Xaml文件中,那看起来就非常不妙了,比如这样:

    <TextBlock Text="首页"FontFamily =" Segoe WP "FontSize ="24"FontWeight =" Normal "TextTrimming =" CharacterEllipsis "TextWrapping =" Wrap "MaxLines ="2" Foreground="#FF297ACD " ></TextBlock>

    一个看起来还好,但是通常我们的页面上不可能只有这一个控件。要是有上10个20个,那如果要修改其中一个属性可真是得看花了眼啊。

    很幸运,我们在Universal应用的开发中可以把控件的相同属性归纳为资源(Resource),再在需要的时候应用到控件上就可以了。

    有些很重要的单独的属性,以颜色为例,不同控件都会使用,却只有几个值,Universal应用可以把它单独抽象成一种 StaticResource 资源--Brush 。将它应用到控件的 Foreground 或者Background 之类的属性上时,就会像"brush(刷子)"一样把控件变为它的颜色。其中常用的SolidColorBrush 可以写成这样:

    <SolidColorBrush x:Key=" PostTitleFont" Color="#FF297ACD"/>

    将它放到资源字典或者页面的<Page.Resources> 中,就可以通过{StaticResource Brush的x:Key的值} 的形式来应用了。

    而同一种控件的多个相同属性,我们可以把它们归纳成Style这种StaticResource资源,存在当前页面的 <Page.Resources> 中:

    <Page.Resources>

    <SolidColorBrush x:Key=" PostTitleFont" Color="#FF297ACD"/>

    <Style x:Key="PostTitleFont" TargetType="TextBlock">

    <Setter Property="FontFamily" Value="Segoe WP"/>

    <Setter Property="FontSize" Value="24"/>

    <Setter Property="FontWeight" Value="Normal"/>

    <Setter Property="TextTrimming" Value="CharacterEllipsis"/>

    <Setter Property="TextWrapping" Value="Wrap"/>

    <Setter Property="MaxLines" Value="2"/>

    <Setter Property="Foreground" Value="{StaticResourcePostTitleFont }"/>

    </Style>

    </Page.Resources>

    Style 的 TargetType 属性指明了Style可以应用的元素,比如TargetType="TextBlock" 的Style是不能应用到Image 元素上的。而Style中包含的就是要应用的属性了,以 <Setter Property="属性名" Value="属性值"/> 这样的形式。

    那么我们在当前页面的需要应用Sytle的地方,比如上面的情况,就只需要通过Style的x:Key 属性来应用:

    <TextBlock Text="首页" Style="{StaticResource PivotTitleFont}"></TextBlock>

    我们可以看到 Style="{StaticResource PivotTitleFont}" 中的 PivotTitleFont 就是 Style的 x:Key 属性,这样style就能够应用到 TextBlock 上了。

    而且Style还能继承。比如我要一个 PostSubTitleFont, 只要字体比PostTitleFont 小一点。那我就可以这么写:

    <Style x:Key="PostSubTitleFont" TargetType="TextBlock" BasedOn="{StaticResource PostTitleFont}">

    <Setter Property="FontSize" Value="20"></Setter>

    </Style>

    这样一来如果我想改动它们的字体,只要在PostTitleFont中修改就可以了。是不是很方便?

    当然我们通常也不止有一个页面,如果不想在每个页面中都把 Style 和 Brush 都贴一遍,就需要资源字典文件出场了。在我们的项目中添加一个资源字典文件:

    再把我们的Style和 Brush都写在里面。然后在需要使用这些Style和 Brush的页面添加形如下面的代码把资源词典引用上就可以啦:

    <Page.Resources>

    <ResourceDictionary>

    <ResourceDictionary.MergedDictionaries>

    <ResourceDictionary Source="Dictionary.xaml" />

    </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

    </Page.Resources>

    当然,我们既然是Universal应用,能不能把Styl和 Brushe在Windows应用和Windows Phone应用间共享呢?答案是可以的。我们只要把资源文件放在.share项目下面,再在App.xaml中添加它的引用就可以:

    <Application.Resources>

    <ResourceDictionary>

    <ResourceDictionary.MergedDictionaries>

    <ResourceDictionary Source="Dictionary.xaml" />

    </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

    </Application.Resources>

    这样Dictionary.xaml中的Style和 Brush就在Windows应用和Windows Phone应用的所有页面都有效了。

    等等,那Windows应用和Windows Phone应用间有所区别的Style和 Brush怎么办呢?

    也有办法。只要在Windows项目和Windows Phone项目中各添加一个同名的资源词典文件比如DifferentDictionary.xaml,把不同的Style和 Brush写入,再在App.xaml中引用就能够实现了。

    <Application.Resources>

    <ResourceDictionary>

    <ResourceDictionary.MergedDictionaries>

    <ResourceDictionary Source="Dictionary.xaml" />

    <ResourceDictionary Source="DifferentDictionary.xaml" />

    </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

    </Application.Resources>

    这样,我们通过Resource 和资源词典文件大大简化了用户界面设计的实现过程,是不是很方便呢?

    夜间模式

    说到阅读软件的用户体验,就不得不提到夜间模式了。下面就说说我们在Windows Phone应用上实现夜间模式的过程吧。

    大家可能都在Windows Phone 设置的 开始屏幕+主题 中设置过背景和主题色,当我们修改了背景的 黑/白 后,几乎所有的系统应用的背景色和文字的颜色都立刻改变了,连重启应用都不用。

    我们实现的夜间模式正是利用了这个功能。

    在Windows Phone应用中,如果我们设置了当前 Page的 RequestedTheme 属性为Light 或者Dark的话就相当于我们在系统设置里修改了背景黑/白。比如通常情况下我们新建一个应用,默认的情况下都是黑底白字:

    而如果我们把Page的 RequestedTheme 属性设为的话,可以看到在设计视图中应用变成了白底黑字:

    那么我们通过settings页面的一个 ToggleSwitch控件实时切换RequestedTheme这一属性,就可以实时控制应用的各种颜色如背景色,文字颜色为Light或Dark对应的颜色。我们把Light设为日间模式,Dark设为夜间模式。简单一点的情况下可以把 ToggleSwitch 的Toggled事件响应方法设为如下:

    private void ts_LightMode_Toggled(object sender, RoutedEventArgs e)

    {

    if (this.RequestedTheme == ElementTheme.Light)

    {

    this.RequestedTheme = ElementTheme.Dark;

    }

    else

    {

    this.RequestedTheme = ElementTheme.Light;

    }

    }

    接下来如何设置日间模式/夜间模式对应的颜色呢?

    在之前的样式管理一节中我们提到了通过{StaticResource PivotTitleFont } 的形式来应用 SolidColorBrush 资源,但是我们在资源 PostTitleFont 定义的时候只写了一个值,系统会自动帮我们转换么?事实上并没有那么简单。我们需要通过 ThemeResource 类型的资源预先设置好2种模式对应的颜色。应用了这种 ThemeResource 资源以后,这个控件就能够响应 RequestedTheme 属性的变化,即时切换显示对应模式的颜色。

    那么怎样加入这种资源呢?我们可以打开我们的资源字典 Dictionary.xaml ,在里面加入这样一段代码:

    <ResourceDictionary.ThemeDictionaries>

    <ResourceDictionary x:Key="Light">

    </ResourceDictionary>

    <ResourceDictionary x:Key="Dark">

    </ResourceDictionary>

    </ResourceDictionary.ThemeDictionaries>

    这里 x:Key 分别为Dark/ Light 的 ResourceDictionary 中,就是我们存放对应两种模式的资源的地方。比如我们希望页面背景在日间模式下是 蓝色,夜间模式下是深灰色,就可以这么写:

    <ResourceDictionary.ThemeDictionaries>

    <ResourceDictionary x:Key="Light">

    <SolidColorBrush x:Key="myPageBackground" Color="Blue"></SolidColorBrush>

    </ResourceDictionary>

    <ResourceDictionary x:Key="Dark">

    <SolidColorBrush x:Key="myPageBackground" Color="DarkGray"></SolidColorBrush>

    </ResourceDictionary>

    </ResourceDictionary.ThemeDictionaries>

    在我们的page中就可以这样应用 ThemeResource 资源了:

    <Page

    x:Class="my_universal.CnblogsMainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:my_universal"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    RequestedTheme="Light"

    Background="{ThemeResourcemyPageBackground }">

    是不是一点都不难呢?

    另外我们还发现有两点值得注意:

    一是我们可以覆盖系统的 ThemeResource 。我们可以选中任意一个 TextBlock 控件,打开属性栏,选择 Foreground 属性的画笔资源。

    可以看到下方以ThemeBrush结尾的都是系统的 ThemeResource 资源,只要在我们的 x:Key 分别为Dark/ Light 的 ResourceDictionary 里加入和它们同名的资源,就能够覆盖它们了。

    二是对于Flyout 类型的控件,应用到它上面的 ThemeResource 资源是相反的。就是说当RequestedTheme 属性为 Light 时,Flyout 类型的控件会应用 Dark ResourceDictionary 中的资源。反之亦然。

    小结

    今天就先向大家分享这些心得,欢迎大家继续关注和拍砖,让我们共同进步。

    我们的已经发布的应用和代码可以在下面找到:

    Windows Phone Store App link:

    http://www.windowsphone.com/zh-cn/store/app/博客园-uap/500f08f0-5be8-4723-aff9-a397beee52fc

    Windows Store App link:

    http://apps.microsoft.com/windows/zh-cn/app/c76b99a0-9abd-4a4e-86f0-b29bfcc51059

    GitHub open source link:

    https://github.com/MS-UAP/cnblogs-UAP

    MSDN Sample Code:

    https://code.msdn.microsoft.com/CNBlogs-Client-Universal-477943ab

  • 相关阅读:
    目前主要的测试用例设计方法是什么?
    软件的安全性应从哪几个方面去测试?
    软件产品质量特性是什么?
    在您以往的工作中,一条软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?
    简述什么是静态测试、动态测试、黑盒测试、白盒测试、α测试 β测试
    详细的描述一个测试活动完整的过程
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    String是最基本的数据类型吗?
    1、面向对象的特征有哪些方面
    说出Servlet的生命周期,并说出Servlet和CGI的区别。
  • 原文地址:https://www.cnblogs.com/ms-uap/p/4180504.html
Copyright © 2011-2022 走看看