《101 Windows Phone 7 Apps》读书笔记-Silly Eye
課程內(nèi)容
? Animation
? Event Triggers
? Named Resources
? Settings Page
? Color Picker
? Clipping
?
??? Silly Eye是一個非常吸引眼球的應(yīng)用,特別是在一群小孩子中間。該應(yīng)用程序會以一種有趣、近乎瘋狂的方式來展示一個巨大的卡通眼球。展示該應(yīng)用程序,只需要將手機(jī)放在右眼的前面,并假裝它就是你的右眼球。本應(yīng)用程序介紹了一些有用的新技術(shù),并且與創(chuàng)建新的頁面和選擇用戶自定義的顏色相關(guān)。但最重要的是,這是與本書第二部分的主題“Transforms & Animations”中“Animations”相關(guān)的第一個應(yīng)用程序。
?
Introducing Animation
??? 大多數(shù)人看到動畫,就會認(rèn)為是一種類似于卡通的東西,它利用連續(xù)快速地播放圖片來模擬運動效果。在Silverlight中,動畫有一個更加詳細(xì)的定義:在時間軸上改變一個屬性的值。這與運動相關(guān),例如,通過增加元素的寬度來營造一種生長的效果,或者,改變一個元素的不透明度來營造另一種完全不同的效果。
??? 在時間線上改變一個屬性的值有很多種方法。最經(jīng)典的方法是使用定時器,比如,很多前面章節(jié)中使用的DispatcherTimer,以及基于定時器觸發(fā)時間而設(shè)置的周期性回調(diào)方法(Tick事件處理)。在這種方法中,我們可以手動更新目標(biāo)屬性(即基于逝去的時間,通過數(shù)學(xué)計算來決定當(dāng)前的屬性值),直到最終的設(shè)定值。這個時候,我們可以停止計時器,并且/或者刪除事件處理程序。
??? 但是,Silverlight提供了一種更容易使用的動畫機(jī)制,它更加強(qiáng)大,性能要比定時器方法更加出色。這是一種以Storyboard的對象為中心的機(jī)制。Storyboard包含了一個或多個特定的動畫對象,它們被應(yīng)用到特定元素的指定屬性中。
??? Silly Eye使用了三個Storyboard來實現(xiàn)動畫。為了理解Storyboard的概念和工作原理,我們來學(xué)習(xí)以下三個內(nèi)容:
? 與瞳孔相關(guān)的 Storyboard
? 與虹膜相關(guān)的 Storyboard
? 與眼瞼相關(guān)的 Storyboard
?
The Pupil Storyboard
???? 下面是Silly Eye應(yīng)用程序中,將Storyboard應(yīng)用到瞳孔中,使其進(jìn)行重復(fù)地擴(kuò)張和縮小。其注意點如下:
? Storyboard.TargetName這個可附加的屬性表明,該動畫被應(yīng)用到本頁面中一個名為Pupil的元素中,而Pupil是一個橢圓。
? Storyboard.TargetProperty這個可附加的屬性表明,Pupil的StrokeThickness屬性被設(shè)置了動畫效果。
? Storyboard中的DoubleAnimation表明,StrokeThickness這個值會在半秒鐘之內(nèi),從100變?yōu)?0。DoubleAnimation中的“Double”代表了目標(biāo)屬性的類型(因為StrokeThickness類型是double)。
? 因為AutoReverse被設(shè)置為true,所以,在StrokeThickness達(dá)到70時,會自動從70變?yōu)?00。由于RepeatBehavior被設(shè)置為Forever,所以只要應(yīng)用程序啟動以后,這種重復(fù)的動作就會一直持續(xù)。
? EasingFunction屬性(設(shè)置為ElasticEase的實例)控制著StrokeThickness值是如何在時間線上進(jìn)行改寫的。這部分的內(nèi)容會在下面的“Interpolation”節(jié)介紹。
開始動畫中,storyboard的Begin方法調(diào)用如下:
this.PupilStoryboard.Begin();
??? 這個動畫在整個應(yīng)用程序中表現(xiàn)出來的效果如圖12.2所示。Pupil這個橢圓的元素在背后代碼中被賦為亮藍(lán)色的畫刷。
圖12.2 PupilStoryboard使得Pupil的stroke(藍(lán)色部分)厚度從100縮小到70,因而使得黑色填充變大。
??? 在XAML中,有一種方法來觸發(fā)storyboard的所有行為。因此,我們沒有必要在背后代碼中調(diào)用它的Begin方法。我們可以為一個元素的Triggers屬性添加一個事件觸發(fā)程序。幸虧這個特殊的BeginStoryboard元素,在grid的Loaded事件中,它會內(nèi)部調(diào)用storyboard 的Begin方法。而Loaded事件是Silverlight事件觸發(fā)中支持的唯一一個事件。
?
Types of Animations
??? Silverlight 提供了animation類來實現(xiàn)四種不同的數(shù)據(jù)類型:double、Color、Point和Object。在Silly Eye應(yīng)用程序中,只使用了double屬性。剩余的類型在第15章“Mood Ring”中介紹。如果我們想要在時間線上改變元素中double類型的屬性值(比如Width、Height、Opacity、Canvas.Left等等),我們可以使用DoubleAnimation的實例。如果我們想要在時間線上改變元素中Point類型的屬性值(比如一個線性漸變brush的StartPoint和EndPoint屬性),我們可以使用PointAnimation的實例。目前為止,由于大量的double類型的屬性需要動畫效果,所以DoubleAnimation是最常用的動畫類。
并不是所有的屬性都可以做動畫效果,即使它的數(shù)據(jù)類型與動畫類使用的數(shù)據(jù)類型匹配!
本章內(nèi)容所討論的動畫機(jī)制,只有那些被稱為“依賴項屬性”(dependency property)的類型才能夠使用。幸運的是,大部分視覺元素中的屬性就是該類型的。依賴項屬性的有關(guān)內(nèi)容會在第18章“Cocktails”中討論。與判斷一個事件是否是“路由事件”(routed event)類似,我們可以通過檢查類中所包含的一個名為PropertyNameProperty的DependencyProperty類型的靜態(tài)字段來決定該屬性是否是依賴項屬性。如果該類中包含了這種字段,如ellipse類中的StrokeThicknessProperty字段,那么它就是一個依賴項屬性。
??? 為了達(dá)到理想的效果,思考一個元素的哪些屬性來做動畫,這需要通過一些試驗來決定。例如,如果我們想要一個元素以漸變的方式出現(xiàn),那么,對它的Visibility屬性做動畫就沒有任何意義,因為在Collapsed 和 Visible兩者之間沒有中間值。相反,我們應(yīng)該對它的Opacity屬性做動畫,它的值是double類型的,范圍從0到1。
?
Interpolation
??? 認(rèn)識下面這點很重要:在默認(rèn)情況下,DoubleAnimation通過時間線上的線性插值來達(dá)到平緩地改變double類型的屬性值。換句話說,在一秒鐘之內(nèi),如果該值從50增加到100,那么,在0.1秒的時刻,它的值就是55(時間增加10%,其值也線性增加10%),在0.5秒的時刻,它的值就是75(時間增加50%,其值也線性增加50%),以此類推。這也就是圖12.2中,StrokeThickness屬性的中間值是85的原因。
??? 但是,Windows Phone應(yīng)用程序中使用的大部分動畫是非線性的。而且,他們更傾向以突然加速或者突然減速的方式從一個值改變到另一個值。這種方式使得動畫變得妙趣橫生。我們可以通過應(yīng)用一個緩和的函數(shù)來實現(xiàn)這種非線性的動畫效果。
??? 這種過渡函數(shù)負(fù)責(zé)屬性值從起始到最終值之間的自定義插值。Pupil Storyboard使用了名為ElasticEase的函數(shù)來實現(xiàn)這種行為。圖12.3展示了屬性值從100減小到70時,使用默認(rèn)的線性變換和彈性變換之間的差異。在這種情況下,85這個中間值并不是在中間時間點達(dá)到,它其實更接近于終點時才達(dá)到。
圖12.3 ElasticEase過渡函數(shù)極大地改變了double類型值從100減小到70的方式。
??? Silverlight提供了11個不同的過渡函數(shù),每個函數(shù)有三種不同的模式,有些函數(shù)提供了更深層次的屬性行為自定義。例如,ElasticEase具有Oscillations 和 Springiness 屬性,默認(rèn)設(shè)置為3。在實際應(yīng)用中,如果我們想要在動畫中加入自定義的函數(shù),那么這種自定義行為的可能性是無窮無盡的。與默認(rèn)的線性過渡相比,本應(yīng)用中使用的過渡函數(shù)為用戶提供了一種完全不同的體驗。
??? 附錄D“Animation Easing Reference”中展示了每個內(nèi)置過渡函數(shù)的行為。我覺得這些函數(shù)非常有用,因為每次當(dāng)我想要設(shè)計一個新的動畫時,我都會回去參考這些函數(shù)。
另一種產(chǎn)生非線性動畫的方法
過渡函數(shù)并非是產(chǎn)生非線性過渡動畫效果的唯一方法。第14章“Love Meter”中討論的Keyframe animations,使得我們可以利用不同的差值方法,將一個動畫分解為多個片段。
?
The Iris Storyboard
??? Silly Eye應(yīng)用程序?qū)⒁韵耂toryboard應(yīng)用到了一個名為Iris的canvas控件中,使得眼球看上去在左右移動。其注意點如下:
? TargetProperty的語法與其名稱相比,稍顯復(fù)雜。當(dāng)它設(shè)置為一個可附加的屬性(如Canvas.Left)時,它必須被包含在括號內(nèi)。
? 該動畫使用了一個不同的過渡函數(shù),使得其運動的邊界更加明顯。關(guān)于BounceEase的行為,請參考附錄D。
? 該動畫缺少了From值!這是可行的,而且我們推薦這樣處理。當(dāng)From值沒有指定時,動畫就從目標(biāo)屬性的當(dāng)前值開始,而不管該值大小為多少。同樣,一個動畫可以指定From值,但并不指定To值!這樣的話,動畫就從屬性的指定值開始,到當(dāng)前值為止。
??? 為了達(dá)到平緩的效果,將From設(shè)置為缺省是很重要的,特別是動畫開始于一個可重復(fù)的用戶輸入。比如,在用戶點擊一個界面元素時,開始它增長的動畫,那么,每次快速的點擊會使得其大小迅速變回From設(shè)定的值。但是,通過缺省的From值設(shè)定,隨后的點擊也會使動畫從當(dāng)前值開始,使得動畫更加的平滑和自然。
在目標(biāo)屬性值無法插值的情況下,我們必須指定From 和 To 的值!
假如我們嘗試著為一個auto-sized元素的寬度或者高度做動畫效果,而它的From和To沒有指定,那么,動畫效果就不會出現(xiàn)。當(dāng)元素的寬度或者高度被設(shè)置為Double.NaN(非數(shù)值)時,它的大小是自適應(yīng)的。因為當(dāng)兩個值中存在一個非數(shù)值的數(shù)時,DoubleAnimation也就無法完成插值的操作。而且,將動畫應(yīng)用到ActualWidth或者ActualHeight中去(它們被設(shè)置為真實的寬度或高度值,而非NaN),這并不是一個好的選擇。因為這些屬性是只讀的,而且并不是依賴項屬性。相反,為了有動畫效果,我們必須顯式地設(shè)置目標(biāo)元素的寬度/高度。
??? 對于Pupil Storyboard來說,我們必須調(diào)用Storyboard的Begin方法來使得它開始工作。
??? 動畫的效果如圖12.4所示。Iris Canvas 除了包含 Pupil ellipse(事實上,它的外圍就是Iris)以外,還包括另外兩個Ellipse,它們?yōu)镮ris增添了“光澤”。因為Canvas控件的位置加入了動畫效果,所以其包含的所有視覺元素都會一起移動。
圖12.4 IrisStoryboard水平移動Iris Canvas,其值從287(它初始的Canvas.Left值)增加到543。
??? 動畫效果類中,也有一個名為 By 的字段,它可以用來代替 To 字段。下面的動畫意味著“在當(dāng)前屬性值的基礎(chǔ)上,增加256”:
<DoubleAnimation By=”256” Duration=”0:0:2”/>
??? 對于縮減當(dāng)前值時,出現(xiàn)負(fù)值的情況也是支持的。
?
The Eyelid Animation
??? Silly Eye應(yīng)用程序中使用的最后一個storyboard,用來對具有皮膚顏色的Eyelid Ellipse模仿眨眼的效果。對于Pupil Ellipse來說,皮膚顏色的畫刷在背后的代碼中進(jìn)行設(shè)置。其注意點如下:
? Storyboard.TargetName 和 Storyboard.TargetProperty 這兩個屬性被設(shè)置為attachable的原因是:它們可以在單獨的動畫中使用,而不用去理會任何Storyboard中的設(shè)置。該Storyboard以 Eyelid Ellipse 中的 Height 和 Canvas.Top 這兩個屬性為目標(biāo)。因此,單個目標(biāo)的名字被標(biāo)記在了Storyboard上,但是多個不同的目標(biāo)屬性被用來標(biāo)記多個不同的動畫效果。
? Canvas.Top 與 Height 具有同步的動畫效果,所以橢圓在垂直縮小的同時,保持在中間的位置。下一章介紹的“Transforms”,提供了一種更加快捷的方法來實現(xiàn)這個效果。
? 這兩種動畫都使用了默認(rèn)的線性插值方法。它們的移動速度如此之快,以至于沒有必要再去嘗試別的更具生命力的方法。
? Storyboard不僅僅是一個簡單的用來給相關(guān)的物體實現(xiàn)動畫效果的容器。該Storyboard具有自身的持續(xù)行為和重復(fù)行為!這兩種動畫只持續(xù)了0.2秒鐘的時間(0.1秒之內(nèi)將屬性的當(dāng)前值從380減小到50,另外的0.1秒鐘之內(nèi),由于其auto-reverse設(shè)置,將屬性值變回到原來的值)。但是,因為給Storyboard的持續(xù)時間是3秒鐘,而且它自身具有auto-reverse設(shè)置(并非是它的子元素),動畫在后面的時間里面保持不動,知道最后3秒時間消耗完。然后,持續(xù)0.2秒鐘的動作再次開始,之后便是2.8秒鐘的靜止時間。因此,該Storyboard使得眼睛眨得非???#xff0c;且在3秒鐘發(fā)生一次。
??? 這種動畫的效果如圖12.5所示(在C#中調(diào)用 Begin 方法開始動畫)。因為Eyelid Ellipse與背景的顏色一致(有意在其左邊的相鄰區(qū)域用黑色做填充),我們就無法看到Eyelid Ellipse本身。相反,一旦Ellipse的高度(380)小于其填充厚度的兩倍(400),我們可以看到其內(nèi)部的空間急劇縮小到0。
圖12.5 Eyelid Storyboard 壓縮 Eyelid Ellipse的高度,并向下移動,使其保持居中。
?
Storyboard and Animation Properties
??? 我們已經(jīng)了解了 Duration、AutoReverse 和 RepeatBehavior 屬性,它們可以應(yīng)用到單獨的動畫或者一個完整的Storyboard中去。總的來說,有6種屬性可以應(yīng)用到 Storyboard 和Animation 中去:
? Duration:Animation 或者 Storyboard 的長度,默認(rèn)值為1秒。
要謹(jǐn)慎指定duration的值!
一個 duration 的字符串格式與 TimeSpan.Parse 這個接口函數(shù)的格式相同:
????????????????????????????????????????????????? days.hours:minutes:seconds.fraction
這里允許使用快捷方式,所以我們不用指定每個字符串。但是,它的行為可能不是如你所愿。字符“2”表示2天,而非2秒。字符串“2.5”表示2天零5個小時!字符串“0:2”表示2分鐘。如果大多數(shù)動畫都不能超過幾秒鐘的時限,那么,典型的使用格式就是 hours:minutes:seconds 或者 hours:minutes:seconds.fraction。所以,2秒可以表示為“0:0:2”,半秒可以表示為“0:0:0.5”或者“0:0:.5”。
? BeginTime:動畫或者Storyboard延時開始的時間長度,由一個具體的時間值表示,默認(rèn)為0。對于子元素的動畫,Storyboard可以使用自定義的BeginTime值,使得它們可以相繼開始動畫,而非同時開始。
? SpeedRatio:持續(xù)時間(Duration)的乘子,默認(rèn)為1。我們可以將它設(shè)置為任意的大于0的double類型的值。一個小于1的值能夠減緩動畫的速度,一個大于1的值能夠加速動畫的速度。SpeedRatio不會影響B(tài)eginTime。
? AutoReverse:該屬性設(shè)置為True時,使得動畫或者Storyboard達(dá)到終點以后,實現(xiàn)自動回播?;夭セㄙM同樣長度的時間,所以SpeedRatio也會影響回播。需要注意的是,通過BeginTime指定的延時并不會影響回播。回播一般會在正常的動畫結(jié)束以后,立即啟動。
? RepeatBehavior:可以設(shè)置為一個時間段,或者設(shè)置為一個字符串,例如“2x”、“3x”或者“Forever”。因此,我們可以使用RepeatBehavior,使得動畫的持續(xù)時間減短(或者減少他們的持續(xù)時間),或者使得動畫自動重復(fù)多次(甚至可以是一個帶小數(shù)的倍數(shù),如2.5倍),或者是永遠(yuǎn)重復(fù)動畫(本章就是使用這個方法)。如果AutoReverse設(shè)置為True,那么,回播操作也會重復(fù)。
? FillBehavior:可以設(shè)置為 Stop,而它的默認(rèn)值為 HoldEnd,使得相關(guān)的動畫完成以后,其屬性值恢復(fù)到動畫之前的值。
?
The Total Length of an Animation
??? 通過使用諸如BeginTime、SpeedRatio、AutoReverse和RepeatBehavior屬性,可以對動畫做多方面的調(diào)整,在動畫開始以后,測試其持續(xù)總時間的長度是有難度的。它的Duration值當(dāng)然不足以描述真正的時間長度!相反,以下的公式描述了一個動畫真正的持續(xù)時間:
總時間= BeginTime +(Duration *(AutoReverse ? 2:1)* RepeatBehavior)/ SpeedRatio
??? 這可以在RepeatBehavior屬性指定為一個double類型的值時使用(或者使用它的默認(rèn)值1)。如果RepeatBehavior設(shè)置為一個時間段,那么總的時間長度就是RepeatBehavior的值加上BeginTime的值。
?
The Main Page
??? Silly Eye主頁面的XAML包含了一些矢量圖片,一個應(yīng)用程序欄,以及三個Storyboard。它同樣包含了一個“使用說明頁面”,暗示用戶點擊屏幕開始應(yīng)用,如圖12.6所示。因此,我們一開始可以展示應(yīng)用程序欄,但是應(yīng)用程序開始運行時,它就隱藏了,因為屏幕上顯示的按鈕會妨礙應(yīng)用程序的效果。介紹頁面暗示用戶他們可以通過點擊屏幕,在任何時候達(dá)到重新調(diào)出應(yīng)用程序欄的目的。
圖12.6 應(yīng)用程序欄只有在“介紹頁面”出現(xiàn)使可見
? 應(yīng)用程序欄包含了導(dǎo)向設(shè)置頁面、說明頁面和關(guān)于頁面的鏈接。前兩個頁面會在下面兩節(jié)中介紹。我們已經(jīng)在第6章“Baby Sign Language”中學(xué)習(xí)了關(guān)于頁面。我們認(rèn)為,設(shè)置頁面的鏈接作為按鈕放置在應(yīng)用程序欄,要好于一個菜單項,因為在本應(yīng)用程序中,用戶對設(shè)置進(jìn)行自定義也是一件很正常的事情(在應(yīng)用程序的正常操作過程中,應(yīng)用程序欄不會引入視覺上的混亂,因為它是隱藏的!)。
? 注意,三個Storyboard資源的名稱被命名為“x:Name”,而不是“x:Key”!這是一種方便的手段,使得我們可以更加方便地使用背后的代碼。在我們給資源命名以后,它就可以作為字典中的一個鍵來使用,或者作為C#生成的一個字段。
? 顯式的From值已經(jīng)從Pupil Storyboard的動畫中移除了,因為它并不是必須的。這部分內(nèi)容已經(jīng)在本章進(jìn)行了介紹,它有助于理解動畫是如何工作的。
? IntroTextBlock元素用來監(jiān)聽用戶的點擊,并且隱藏IntroPanel。它的寬度值為700,比整個頁面的寬度還要大,因為如果它距離應(yīng)用程序欄太近的話,用戶在想點擊應(yīng)用程序欄時,可能不小心點到它(然后就會隱藏應(yīng)用程序欄)。
?
The Code-Behind
? 由于XAML中的x:Name標(biāo)記,通過各自的名稱,三個Storyboard在構(gòu)造函數(shù)中初始化。
? 頁面的Clip屬性被設(shè)置為一個屏幕大小的矩形區(qū)域。這樣做是為了在動畫頁面切換期間,防止對屏幕以外的矢量圖形進(jìn)行渲染。這不僅避免了出現(xiàn)非常奇怪的視覺元素,而且也有助于提高應(yīng)用程序的性能。所有具有這個Clip屬性的UI元素可以被設(shè)置為一個任意的幾何圖形。
?
Geometries Used for Clipping
??? Clip屬性可以被設(shè)置為一些幾何形狀,這些形狀與第5章“Ruler”中介紹的形狀對象類似,但又有不同。我們可以使用 RectangleGeometry、 EllipseGeometry 、LineGeometry、PathGeometry 或者是 GeometryGroup 來組合多個幾何形狀。附錄E“Geometry Reference”中將會討論這些幾何形狀。
? 我們使用兩個存儲設(shè)置來存儲皮膚和眼睛顏色的值,它們在OnNavigatedTo事件處理中使用。在OnNavigatedFrom事件處理中,它們沒有必要進(jìn)行儲存,因為設(shè)置頁面會進(jìn)行處理。這些設(shè)置的內(nèi)容在單獨的Settings.cs文件中定義。事實上,眼睛默認(rèn)的顏色就是手機(jī)的主題強(qiáng)調(diào)色,就和本章圖片中展示的藍(lán)色一樣。
? IntroPanel的可視性(以及應(yīng)用程序欄)放置于頁面的狀態(tài)中,所以如果頁面在休眠和激活以后,看上去是一致的。無論頁面經(jīng)歷了多大的改變,也不要忘記使用頁面設(shè)置,有了它,在應(yīng)用程序經(jīng)歷被打斷、又重新激活時,我們可以快速并且自動地恢復(fù)頁面狀態(tài)。
? IntroTextBlock的對齊方式在OnOrientationChanged事件中進(jìn)行調(diào)整,這樣做是為了保持它與應(yīng)用程序欄保持對立的位置關(guān)系。前面已經(jīng)敘述過,在手機(jī)的方向為landscape right時,應(yīng)用程序欄出現(xiàn)在屏幕的左邊;當(dāng)手機(jī)的方向為landscape left時,應(yīng)用程序欄出現(xiàn)在屏幕的右邊。
?
The Settings Page
??? 設(shè)置頁面如圖12.7所示,它使得用戶可以為眼睛和皮膚選擇不同的顏色。
圖12.7 設(shè)置頁面使得用戶可以選擇Silly Eye應(yīng)用程序的顏色。
在系統(tǒng)自帶的設(shè)置程序中,如何為我們的應(yīng)用程序添加一個設(shè)置頁面?
在目前Windows Phone 7.0的版本中,我們還無法做到這點。雖然設(shè)置應(yīng)用包含了一個系統(tǒng)設(shè)置的列表和一個應(yīng)用設(shè)置的列表,但是后者只是針對系統(tǒng)自帶的應(yīng)用來說的。相反,我們需要為我們的應(yīng)用程序添加設(shè)置頁面,使其用戶體驗和系統(tǒng)自帶的設(shè)置頁面一致。換句話說,對于我們的設(shè)置頁面,應(yīng)該使用“SETTINGS”作為應(yīng)用程序的名稱出現(xiàn)在標(biāo)準(zhǔn)的header中,使用應(yīng)用程序的名稱作為頁面標(biāo)題,如圖12.7所示。
??? 對于設(shè)置頁面的設(shè)計指導(dǎo),請參考第20章“Alarm Clock”中的內(nèi)容。
??? 頁面設(shè)計的注意點如下:
? 該頁面的自定義header樣式從App.xaml文件獲得。對于本書中剩余的應(yīng)用程序來說,App.xaml.cs這個文件同樣提供了自定義的頁面過渡效果,如第19章“Animation Lab”所述。
? 那兩個可點擊的區(qū)域顯示了當(dāng)前的顏色,看上去和按鈕很像,但實際上它們只不過是矩形填充。它們的MouseLeftButtonUp事件處理包含了用戶對于每種界面顏色改變的處理。
? 雖然在不同的方向模式下,內(nèi)容完全符合屏幕,但是主要的stack panel控件被放置在scroll viewer內(nèi)。這對于用戶來說,很適合觸摸操作,因為用戶可以用手指拖動屏幕查看內(nèi)容,并使他們確信瀏覽了屏幕中所有的內(nèi)容。
??? 在很多頁面中,例如設(shè)置頁面、說明頁面或者是關(guān)于頁面,將內(nèi)容放置于scroll viewer中是一個很好的選擇,即使所有的內(nèi)容可以用一個屏幕來容納。那樣的話,用戶可以用手指做一個快速的拖動,從視覺上就可以判定沒有更多的內(nèi)容可以看了(因為scroll viewer控件的scroll-and-squish特性)。這種反饋是非常另用戶滿意的。當(dāng)屏幕對于用戶的拖動沒有反應(yīng)時,用戶會認(rèn)為他不夠用力,可能會再嘗試一次。
?
The Code-Behind
??? 為了使用戶能夠改變每個顏色,該頁面會將用戶導(dǎo)航到一個顏色選擇頁面,如圖12.8所示。這個特性頁面被本書中的很多應(yīng)用程序共用,包含在本書的源代碼中。它提供了一個標(biāo)準(zhǔn)顏色的調(diào)色板,它也允許用戶自定義顏色的色相、飽和度和亮度,不管是通過交互式的界面或者是輸入一個十六進(jìn)制的數(shù)值(或者是任何能夠被XAML解析的字符串,如“red”、“tan”或者是“l(fā)emonchiffon”)。調(diào)整顏色的不透明度是可選的。
圖12.8 顏色選擇器頁面為用戶提供了一個漂亮的頁面來選擇顏色。
??? 顏色選擇器頁面通過查詢字符串可以接受以下四種參數(shù):
? showOpacity-默認(rèn)值為True,可以將其設(shè)置為False來隱藏opacity slider。它也會將調(diào)色板頂層的透明顏色移除,并且阻止用戶輸入透光的顏色。因此,當(dāng)我們將它設(shè)置為False時,我們可以確定一個不透明的顏色將會被選中。
? currentColor-當(dāng)頁面呈現(xiàn)時,開始被選擇的顏色。它必須作為一個對XAML有效的字符串參數(shù)傳入。如果指定為一個十六進(jìn)制的數(shù),“#”必須被移除,這樣做是為了與URI混淆。
? defaultColor-在顏色選擇器頁面中,用戶點擊reset按鈕時,可以得到的顏色。它指定的字符串格式要求與currentColor一樣。
? settingName-隔離存儲空間中使用的名稱,在從頁面返回時,選定的顏色可以從中被找到。在構(gòu)造一個Setting的實例時,用到了同樣的名字。在列表12.4的OnNavigatedTo方法中,當(dāng)從顏色選擇器頁面返回時,它自動選擇新的顏色數(shù)值,那只是因為導(dǎo)航到顏色選擇頁面之前,需要調(diào)用ForceRefresh方法。第20章詳細(xì)介紹了這種方法。
??? 使用本書的顏色選擇器頁面(或者類似的頁面)為用戶提供一種簡便高效的顏色選取方法。在當(dāng)前的版本中,該頁面的主要缺點是只支持portrait的屏幕方向。因此,在landscape屏幕方向下,使用硬件鍵盤輸入一個顏色的十六進(jìn)制數(shù)的用戶體驗并不好。
?
The Instructions Page
??? 本應(yīng)用程序的說明頁面如圖12.9所示,其注意點如下:
圖12.9 Silly Eye應(yīng)用程序中的說明頁面
? 和設(shè)置頁面采用的方法一樣,主要的內(nèi)容被放置在scroll viewer中,從而提示用戶沒有更多的內(nèi)容可以瀏覽。
? 和主頁面中的intro pane一樣,單個text block利用LineBreak元素來格式化其文本內(nèi)容。
? 對于背后的代碼文件-InstructionsPage.xaml.cs,在其構(gòu)造函數(shù)中,只包含了對InitializeComponent方法的調(diào)用。
轉(zhuǎn)載于:https://www.cnblogs.com/dearsj001/archive/2012/08/22/101App4WP7_SillyEye.html
總結(jié)
以上是生活随笔為你收集整理的《101 Windows Phone 7 Apps》读书笔记-Silly Eye的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL 错误对照表
- 下一篇: 关于多边形内点数问题的一些变形