随笔-193  评论-1119  文章-1  trackbacks-4

《101 Windows Phone 7 Apps》读书笔记-ALARM CLOCK

课程内容

Ø 隔离存储空间

Ø 设置

Ø 设置页面向导

Ø Toggle Switch控件

Ø 使用自定义字体

    Alarm Clock模仿的是一种有点复古的数字闹钟。它具有固定的显示,上面的分段可以根据需要进行打开或者关闭。它不仅能够显示当前的时间、周几,而且可以设置午休的闹钟(即使它被锁屏界面遮盖,闹钟会在程序运行的状态下发出提醒)。

    Alarm Clock提供了一些诸如颜色、时间格式和震动方式等与用户可设置的功能。它也能够保留状态信息,比如闹铃是否被打开,什么时间应该发出提醒。所有的这些都是通过Setting类来完成的,之前介绍的几乎所有应用也是使用了Setting类。在第三部分-“本地数据存储和获取”中,我们会更加深入地研究Setting类的工作机制以及数据的存储和获取。

 

Setting and Isolated Storage

    隔离存储空间(Isolated storage)是一个提供给每个应用程序的特殊文件夹,它被用来存储任意的数据文件。这个文件夹下的文件与指定的应用程序是分隔开的。一个应用程序无法获取另一个应用程序的隔离存储空间。即使应用程序想要与其他应用共享数据,它也无法通过隔离存储空间来实现。

    正如第22章的“Notepad”应用所讲,尽管我们可以从隔离存储空间中读取或者写入文件,但是本书的大部分应用程序都使用了Setting类,这就向我们展示了一个更加简单的机制,它被称为应用设置(application settings)。在System.IO.IsolatedStorage命名空间中有一个静态的IsolatedStorageSettings.ApplicationSettings字典(dictionary)。我们可以使用一个字符串键值在该字典中存储任何的可序列化对象。当应用程序退出的时候(无论是关闭或者休眠),ApplicationSettings中的内容会自动序列化,存储到隔离存储空间的文件中。当应用程序开始运行或者被重新激活时,ApplicationSettings会自动被之前存储的数据所填充。列表20.1包含了通用Setting类的实现,它封装了ApplicationSettings

    虽然通过ApplicationSettings进行数据存储和数据获取是一种直接的方式,但与之不同的是,Setting类能够有效地减少应用程序的代码量。因为使用ApplicationSettings时,用户必须准备那些不在字典中的keys(一般是首次运行程序时使用的)。Setting类支持默认值的规范,它会将该值缓存起来,因此,每次不用从字典中来获取。

    除非应用程序运行时,你不想它自动加载大量的数据,使用ApplicationSettings(或者本书的Setting类)来存储应用程序的用户设置和其它状态已经足够了。与从隔离存储空间中读取/写入数据相比,这种方式要简单得多。

    ForceRefresh方法解决了外部代码改变underlying dictionary entry的情况。这也影响了本书中每个使用color picker的应用程序,因为color picker直接更新ApplicationSettings

    尽管IsolatedStorageSettings定义了一个保存的方法,但是你不必调用它,因为当你的应用程序退出时,所有的内容会被自动保存。但是,你的应用程序必须优雅地退出使得其实现。因此,唯一手动调用保存方法的原因是在应用程序崩溃之后、关闭或者休眠之前,确保数据不丢失。

    在应用程序更新或者卸载以后,隔离空间中的数据会发生什么?

    当应用程序更新到一个新的版本时,它隔离空间中的数据仍旧会被保存。当应用程序被卸载时,它隔离空间中的数据会被删除。在此之后,没有办法再恢复数据了。

    每个应用程序可以获得多大的隔离存储空间?

    隔离存储空间只受手机配置的影响。与web版本的silverlight不同,对于每个应用程序的隔离存储空间,并没有人为引入空间大小的限制。

 

The Settings Page

    Alarm Clock包含四个页面:主页面、提醒页面、设置页面和引导页面(本章不做介绍)。因为设置页面是本章的一个内容,所以我们会先研究Alarm Clock的设置页面。该页面如图20.1所示。

clip_image002

图20.1 Alarm Clock所展示的设置页面

    该页面利用了Silverlight for Windows Phone Toolkit中的 toggle switch控件。从功能上来看,toggle switch控件的作用和check box类似。从视觉上来看,它的默认外观就是一个滑动开关。

    虽然toggle switch是内容控件,但是你不想涉及到它的Content属性。它默认将控件当前状态对应的“打开”或者“关闭”显示出来(通过IsChecked属性实现),这与设备内置应用的滑动开关行为相匹配。而你应该将它的Header属性设置成一个描述性字符串。

    针对应用程序设置页面的外观和行为,Windows Phone 团队发布了若干指导意见:

Ø 页面应该具备标准的双段文字标题,即使页面的其它部分具备滚动条,它也不能滚动。

Ø 显示应用名称的text block应该设置为“SETTINGS”,就像把用户指引到了设备的Settings应用页面。

Ø 显示页面名称的text block应该设置为应用的名称,这也是和设备的Settings应用页面外观保持一致。

Ø 当用户改变了一项设置,应用程序应该立刻体现出来。最好不要有页面级别的应用/取消按钮。

Ø 对于一些特殊的不可逆的设置,需要给用户弹出消息框,使得他能够有机会进行取消操作。

Ø 尽量保持设置页面的简洁。

Ø 避免设置多于1页的设置页面。如果内容无法在1个页面显示,那么就可以利用scrolling或者pivot控件来处理。

    如何在设备内置的Setting页面中加入应用程序的页面?

    这是无法实现的。在当前的Windows Phone版本中,第三方应用只能在其应用本身中具备设置页面。

    可以通过浏览设备内置的设置页面来思考应用程序的设置页面该如何设计。

    color picker页面利用传入的settingName作为参数,直接把选定的颜色写入到IsolatedStorageSettings. ApplicationSettings中去。这也是为什么它能够与任何应用程序使用的Setting对象配合的原因,同时,也说明了在重新获取设置页面时,为什么要调用ForceRefresh方法。

    如果你的应用程序使用了特别的设备功能(如利用位置服务来获取邮政编码,而无需用户手动输入),微软推荐应用程序的设置页面应当提供设置来禁止这些功能。当然,应用程序代码没有禁止这种功能的能力,但是,应用程序可以不调用这些代码,从而达到不使用设备某种功能的目的。

 

The Alarm Page

    Alarm Page如图20.2所示,可以说是第二个设置页面,但它被专门用来设置提醒的打开、关闭与时间的设定。它同时也具有一个测试提醒音乐的按钮,用户可以确定音量是否足够吵醒他们。

clip_image002[5]

图20.2 alarm页面展示应用程序最重要的设置

    虽然应用程序应当避免使用多于1页的设置页面,但该页特别的重要,以至于需要单独的一页。用户希望每晚访问Alarm Page来确保闹铃设置正确,但他们并不需要访问设置页面。

注意:

Ø 本应用程序利用Part V-“Audio&Video”的音效API来产生提醒铃声。

Ø 与第9章“Fake Call”一样,time picker控件的ValueChanged事件用于将新的值应用到相应的设置中去。没有这部分的话,由于time picker控件引入的页面导航,用于设置time picker值的OnNavigatedTo部分的代码会覆盖掉新选择的值。

 

The Main Page

    主页面看上去很像一个实际的数字闹钟,它具有时间、日期和闹铃信息显示。它的根节点包含了许多分栏,主要为了均匀分布星期一到星期日的显示。列表20.6包含了该页面的XAML,图20.3展示了页面的布局,并且其根节点设置为ShowGridLines=”True”。

clip_image002[8]

图20.3 显示了网格的主页面

注意:

Ø 与第四章“Stopwatch”类似,该页面使用了一个定时器来持续刷新时间显示,周期为一秒,这也用来闹铃响起时,每秒钟一次的振动。

Ø 该页面也使用了与第四章相同的屏幕方向锁定方法。

Ø 七个周历的文本框并非在XAML中构建和添加,而是通过背后的代码来实现。因为将它们通过代码中的数组来存放和处理比较方便。

Ø 该页面将ApplicationIdleDetectionMode设置为Disabled,使得应用程序在锁屏和关闭屏幕的情况下继续运行。这也是用户所希望的,而并不是让屏幕保持整晚都亮着。但是,如果用户希望这样,该页面也可以设置UserIdleDetectionMode为Disabled,使得应用程序不会自动锁住。如果用户想要关闭设备屏幕,他们必须手动来完成。

Ø 该页面有一些特殊的功能,比如,它将选定的前景色和背景色应用到application bar和主页面。选定的背景色是应用到网格,而不是整个页面。重新调用它来设置页面的背景色也会无效。

Ø 如果闹铃响起后触摸屏幕,那么会让设备停止闹铃,但5分钟后仍旧会响起(这个5分钟是当前开始的5分钟,如果闹铃不在整数分钟响起,会令用户感到疑惑)。否则,触摸屏幕会改变application bar的可视性。这就为用户提供了更加实际和生动的显示。

Ø 不同的文本框的透明度参数为1时,是亮起的。在透明度为0.1或者0.2时,它们就被关掉了(在实际应用时,该值会有一点偏差)。Timer_Tick事件代码影响着存放周历文本框的数组,它利用DateTime.Now.DayOfWeek(包括0到6的数字)作为数组的下标。

 

TimeDisplay 用户控件

    这个应用的特别之处在于使用七段数码管来显示时间,它有几种方法来实现。比如,我们可以创建基于矢量的图形,根据它们的填充设置,在合适的时间来点亮合适的分段。这个应用程序使用了更加简单的方法:使用自定义字体。列表20.8包含了TimeDisplay用户控件的XAML代码,它实现了七段显示。

    在使用自定义字体之前,确保你具有这个权限!

    虽然使用自定义字体比较简单,但是否合法使用就是另一回事情了。在使用字体之前,应该确保了解它的使用规则。列表20.8使用的自定义字体被称为“Pendule Ornamental”,该字体由Scott Lawrence所创建,可以在通过以下链接地址下载到:http://fontstruct.fontshop.com/fontstructions/show/200136。它遵循Creative Commons Attribution Share Alike license,详细内容请参考以下网页:http://creativecommons.org/licenses/by-sa/3.0/

注意:

Ø 使用自定义字体,只需要将字体文件包含到项目工程中(将其Build Action设置为Content),并在需要使用该字体的text block、text box控件(或者是那些继承字体的子控件)的FontFamily中添加引用。其语法为:

pathAndFilename#fontName

我们可以通过Windows资源管理器来打开字体文件,从而确定fontName的正确值。

Ø 为了达到每个数字显示管灰暗的效果,该用户控件实际上使用了两个重叠的text block。在任何时间,底层的text block的所有分段均被点亮(用88:88表示小时和分钟,用88表示秒),其不透明度设置为0.1。顶层的text block用于显示实际时间,其不透明度设置为1。

Ø 每个text block分为两个不同的部分,一个用于显示小时/分钟,其面积较大;另一个用于显示秒,其面积较小(它们的面积和显示值均可以在代码文件中设置)。这里text block的不同之处在于它的内容属性并非是它的Text属性,而是Inlines属性。尽管类型转换可以把它设置成XAML中的string,但Inlines可以设置为Inline对象的集合。有两个类从抽象的Inline类继承而来,即Run 和 LineBreak。LineBreak类的介绍请参考第八章“Vibration Composer”。

Ø 在Run的实例中,我们可以把它和text block设置成相同的formatting属性。例如,FontFamily, FontSize, FontStyle, FontWeight, Foreground和 TextDecorations等等。因此,Run提供了一种简便的方法来创建text block中具有混合格式的文本内容。

posted on 2012-08-08 15:43 施炯 阅读(...) 评论(...) 编辑 收藏