【Win 10 应用开发】UI Composition 札记(二):基本构件
在上一篇中,老周用一個(gè)示例,演示了框架視圖的創(chuàng)建過(guò)程,在本篇中,老周將給大伙伴們說(shuō)一下 Composition 構(gòu)建 UI 的一些“零件”。
UI Composition 有一個(gè)核心類——對(duì),就是?Compositor 類,它是總生產(chǎn)車間,組成 UI 的各種元素都可以由它來(lái)創(chuàng)建,所以,你會(huì)看到,它公開(kāi)了 K 個(gè)以 Create 開(kāi)頭的方法。我們?cè)诮M建 UI 時(shí)所用到的各種元素都可以調(diào)用這些以 Create 打頭的方法來(lái)創(chuàng)建。
要讓用戶在窗口上看到你所構(gòu)建的 UI 元素,可視化樹(shù)中至少需要一 Visual 對(duì)象。Visual 是一個(gè)基類,在組成可視化樹(shù)時(shí),我們有三種 Visual 可以用。
第一種是?ContainerVisual,它表示一容器,可以向它的?Children 集合中添加子元素,以構(gòu)建復(fù)雜的可視化對(duì)象。
第二種是?SpriteVisual,它從?ContainerVisual 類派生,所以也支持添加子元素。Sprite 是“小仙女”的意思,表明這個(gè)類不僅僅是個(gè)容器,它自身就可以繪制可視化內(nèi)容,所以這個(gè)類用得還是比較多的。它主要公開(kāi)了 Brush 屬性,可以使用各種畫刷來(lái)繪制內(nèi)容。比如,單種顏色填充的畫刷,漸變畫刷,繪制圖形的畫刷等。
第三種是 ?LayerVisual,它也是容器元素,它類似于在視圖中創(chuàng)建一個(gè)圖層,并可以在其中繼續(xù)添加子元素。
?
要呈現(xiàn)多彩燦爛的內(nèi)容,你需要畫刷,因此,UI Compositon 提供各種用途的畫刷。
1、單色畫刷,只有一種顏色對(duì)對(duì)定可視化元素進(jìn)行填充。
2、漸變畫刷,可以設(shè)置多種顏色過(guò)度。
3、Drawing Surface ,這個(gè)強(qiáng)大,相當(dāng)于一塊自由畫布,你可以在上面畫各種東東。你可以畫文本,畫圓形,畫線,畫大象,畫野鴨子。甚至你可以在上面畫一個(gè)正在播放的視頻。繪制代碼是要用C++來(lái)寫,不過(guò)我們可以結(jié)合 Win 2D 組件一起用,這個(gè)老周后面會(huì)繪出例子的。
4、效果畫刷。這種畫刷主要用來(lái)產(chǎn)生一些視覺(jué)效果,比如模糊、銳化、顏色疊加、反相等等。
?
有了可視化對(duì)象和畫刷,我們基本上可以弄出很多東西來(lái)。不過(guò),可能大伙伴們會(huì)想了,要是能模擬一些真實(shí)場(chǎng)景就更佳了。于是,燈光就出場(chǎng)了。燈光就是模擬我們現(xiàn)實(shí)世界中的各種光源,比如小燈泡發(fā)出的點(diǎn)光,手電筒照射的光,或者照射范圍更大的環(huán)境光(如白熾燈)等。
1、SpotLight,這種光源有點(diǎn)像手電筒的光,發(fā)散出去后會(huì)產(chǎn)生一個(gè)錐形區(qū)域。
2、PointLight,類似于一盞小燈泡,光源是一個(gè)點(diǎn),但它可以向四周照射。
3、DistantLight,這種光有點(diǎn)像汽車的遠(yuǎn)光燈(晚上開(kāi)車時(shí)別亂開(kāi)遠(yuǎn)光啊,會(huì)害死人的),也像太陽(yáng)光。總之,這種光源照射面很大,而且光很強(qiáng),傳播距離遠(yuǎn)。
4、AmbientLight,這種光就像你家里,房間里安裝的白熾燈,或者是新型的節(jié)能燈,白白的光,可以照亮整個(gè)屋子,即環(huán)境光。
老周這么一說(shuō),你一定會(huì)覺(jué)得沒(méi)意思,都不知道燈光照起來(lái)是什么效果。別急,老周后面會(huì)給例子的,你會(huì)看到效果的。
?
有刷子,有燈泡,有畫布,你大概覺(jué)得差不多了,可以畫出很多大作了。是的,不過(guò),要是你的大作能夠動(dòng)起來(lái),是不是更生動(dòng)了呢。比如你畫了豬八戒,手里拿著個(gè)大西瓜,要是能讓八戒動(dòng)起來(lái),尤其是嘴巴,一下一下地啃西瓜皮,那該多好。因此,你還需要?jiǎng)赢嫛?/p>
1、關(guān)鍵幀動(dòng)畫。這個(gè)應(yīng)該好懂,就是可以在某個(gè)時(shí)刻設(shè)置一個(gè)關(guān)鍵幀,然后關(guān)鍵幀之間會(huì)自動(dòng)以時(shí)間為基準(zhǔn)產(chǎn)生過(guò)度動(dòng)畫。
2、表達(dá)式。即使用一個(gè)計(jì)算公式來(lái)生成動(dòng)畫所需要的值。比如你要對(duì)可視化元素的不透明度進(jìn)行動(dòng)畫處理,輸入 Opacity * 0.5,表示每次的不透明度變化,最終值都是上一次計(jì)算結(jié)果的一半,比如,不透明度為 100%,進(jìn)行動(dòng)畫后變成 50%,再進(jìn)行一次動(dòng)畫后就成 25% …… 要注意的是,表達(dá)式產(chǎn)生的動(dòng)畫是不能控制時(shí)間的。
?
以上內(nèi)容你不必太認(rèn)真看,就當(dāng)作常識(shí),大致涉獵一下就 OK 了,后續(xù)的博文中,老周會(huì)逐個(gè)介紹的。接下來(lái),我們要了解一下如何構(gòu)建 UI 樹(shù)。
咱們一起來(lái)動(dòng)動(dòng)手,學(xué)習(xí)編程一定要?jiǎng)邮值?#xff08;當(dāng)然,動(dòng)腦子是必須的),如果你能用腳打字,也可以動(dòng)腳。
記得老周一一篇中說(shuō)過(guò)的吧,我們要先實(shí)現(xiàn)自己的一個(gè)視圖,即實(shí)現(xiàn)?IFrameworkView 接口。
class DemoView : IFrameworkView {…… }然后,我們聲明幾個(gè)私有字段。
Compositor mCompositor = null;CoreWindow mWindow = null;SpriteVisual rootVisual = null;要組裝 UI 構(gòu)件,我們需要一個(gè)?Compositor 類的實(shí)例,在這個(gè)例子中,我打算用?SpriteVisual 作為 UI 樹(shù)的根,它既可以用畫刷繪制內(nèi)容,也可以添加子元素,正可謂是一物兩用。
接著,進(jìn)行初始化,此時(shí)我們可以實(shí)例化 Compositor 對(duì)象,或者實(shí)例化其他我們需要的東西。注意此時(shí)不要組建 UI 樹(shù),因?yàn)榇翱谶€未初始化,此時(shí)建UI樹(shù)會(huì)發(fā)生異常。
public void Initialize(CoreApplicationView applicationView){mCompositor = new Compositor();}Load方法我們這里沒(méi)啥要加載的,就留空吧。
public void Load(string entryPoint){// 留著以后用來(lái)養(yǎng)金魚}接下來(lái)是重點(diǎn),SetWindow 方法,此時(shí)窗口已經(jīng)可用,所以此時(shí)可以組建 UI 樹(shù)了。
public void SetWindow(CoreWindow window){mWindow = window;// 創(chuàng)建根元素rootVisual = mCompositor.CreateSpriteVisual();// 這個(gè)是重點(diǎn),必須要有這個(gè) targetCompositionTarget target = mCompositor.CreateTargetForCurrentView();// 指定 UI 根元素target.Root = rootVisual;// 這時(shí)候UI元素上是空白的// 為了能看到東西,我們畫點(diǎn)東西上去CompositionColorBrush backBrush = mCompositor.CreateColorBrush(Colors.Blue);rootVisual.Brush = backBrush;}這里有一個(gè)很重要的東東,大伙要嚴(yán)重注意。在組建 UI 時(shí),你必須調(diào)用?CreateTargetForCurrentView 方法創(chuàng)建一個(gè)?CompositionTarget 實(shí)例,它直接與當(dāng)前的應(yīng)用程序視圖關(guān)聯(lián)的,你必須創(chuàng)建一個(gè)該實(shí)例,然后再把 UI 的根元素賦值給?CompositionTarget 的 Root 屬性。Root 屬性引用的UI元素就作為整個(gè)視圖的根。
而且,這個(gè) target 在整個(gè)視圖的生命周期內(nèi),你只能創(chuàng)建一次,如果設(shè)置了根元素后,你還調(diào)用?CreateTargetForCurrentView 方法的話,你會(huì)收到一條?DCOMPOSITION_ERROR_WINDOW_ALREADY_COMPOSED 錯(cuò)誤,該錯(cuò)誤提醒你,該可視化樹(shù)已經(jīng)組裝過(guò)了,你不能再調(diào)用了。
CreateColorBrush 方法創(chuàng)建一個(gè)單色填充的畫刷,這里我用的是藍(lán)色。
?
在 Run 方法中開(kāi)啟消息循環(huán)。
public void Run(){mWindow.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit);}但是,以上代碼漏了一句,所以一旦運(yùn)行,你只能看到初始屏幕。如下圖。
因?yàn)槟氵€沒(méi)有激活當(dāng)前窗口,故你在?ProcessEvents 之前,要加上這一句。
public void Run(){mWindow.Activate(); mWindow.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit);}因?yàn)槲矣?mWindow 字段引用了當(dāng)前窗口的實(shí)例(就是剛剛上面的 SetWindow 方法中),所以我直接調(diào)用 Activate 方法。如果你沒(méi)有用變量存儲(chǔ)當(dāng)前窗口的實(shí)例,你還可以這樣調(diào)用。
CoreWindow.GetForCurrentThread().Activate();?
最后,在視圖銷毀時(shí),打掃一下衛(wèi)生。
public void Uninitialize(){rootVisual.Dispose();mCompositor.Dispose();mWindow = null;}?
視圖的邏輯弄完了,再實(shí)現(xiàn)一下?IFrameworkViewSource 接口。
class DemoViewSource : IFrameworkViewSource{public IFrameworkView CreateView(){return new DemoView();}}別忘了入口點(diǎn)。
class Program{static void Main(){CoreApplication.Run(new DemoViewSource());}}?
好,大功告成!按下【F5】鍵,你滿懷信心地看著程序啟動(dòng)。結(jié)果傻眼了,FK!怎么一片空白的?
?
咋回事呢?是啊,咋回事呢。再檢查一下代碼,邏輯都對(duì)啊。其實(shí),你之所以看不到東西,是因?yàn)榭梢暬氐拇笮∧J(rèn)是 0,所以,你要回到 SetWindow 方法,給可視化元素設(shè)一個(gè) Size。
public void SetWindow(CoreWindow window){mWindow = window;// 創(chuàng)建根元素rootVisual = mCompositor.CreateSpriteVisual();rootVisual.Size = new System.Numerics.Vector2(300f, 320f); ……}如果必要,你還可以設(shè)置視圖對(duì)象的偏移量,默認(rèn)是 0、0、0,即位于窗口的左上角,注意這個(gè)坐標(biāo)是三個(gè)值的,即XYZ三個(gè)軸,X和Y軸你都懂的,原點(diǎn)在左上角,X軸正方向往右,Y軸正方向往下。至于Z軸嘛,從屏幕里面向外,說(shuō)白了就是正方向指著你。
可以設(shè)置一下偏移量。
public void SetWindow(CoreWindow window){mWindow = window;// 創(chuàng)建根元素rootVisual = mCompositor.CreateSpriteVisual();rootVisual.Size = new System.Numerics.Vector2(300f, 320f);rootVisual.Offset = new System.Numerics.Vector3(0f, 20f, 5f); …… }?
?好了,一切的疑問(wèn)都解開(kāi)了。再運(yùn)行一下,Good,效果出來(lái)了。
?
其實(shí),你還可以讓它帶透明效果的,方法和 XAML 中一樣。
public void SetWindow(CoreWindow window){……rootVisual = mCompositor.CreateSpriteVisual();rootVisual.Size = new System.Numerics.Vector2(300f, 320f);rootVisual.Offset = new System.Numerics.Vector3(0f, 20f, 5f); rootVisual.Opacity = 0.5f; ……}?
再看看效果。
?
?有趣吧,你還可以對(duì)它進(jìn)行旋轉(zhuǎn)的。
rootVisual.RotationAngleInDegrees = 60f;RotationAngle 屬性設(shè)置的旋轉(zhuǎn)角度是弧度角,要用角度進(jìn)行設(shè)置,就用?RotationAngleInDegrees 屬性。
?
你不過(guò)癮的話,還可以調(diào)整整個(gè)三維坐標(biāo)的方向。
rootVisual.Orientation = new System.Numerics.Quaternion(-15f, 5f, 2f, 1f);?
然后就變成這個(gè)樣子了。
?
?怎么樣,有意思吧。本篇就扯到這里,大伙伴只要知道UI元素的組裝方法就可以了,至于說(shuō)那些三維變量如何設(shè)置,這個(gè)可以網(wǎng)上查資料,或者自己摸索,三維方面的東西還是挺復(fù)雜,其實(shí)老周也不是很了解,寫出來(lái)大家交流交流而已。
?
轉(zhuǎn)載于:https://www.cnblogs.com/tcjiaan/p/7784024.html
總結(jié)
以上是生活随笔為你收集整理的【Win 10 应用开发】UI Composition 札记(二):基本构件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 17秋 软件工程 团队第五次作业 Alp
- 下一篇: python常用库之base64