Introduce composition / visual layer api for UWP app. This one sample without using xaml.
這次要來介紹Composition API,這支API是在1511(10586)的時候就已經介紹出來!但是在1607(14393)的更新時變更了XAML interrop的流程~今天先簡單介紹Composition的強大能力!
XAML由Microsoft從WPF時代開始引入至Framework層開始可以做出MVVM的框架,而這樣的框架其實也是從MVC演進過來!但是Composition必須要由UI code-behide的方式來使用~Microsoft composition team的目標是把所有在UWP的XAML都控制項都能和Composition配合!
這邊開始介紹Composition是怎樣的一個概念~
上圖出自 Docs Microsoft
UWP在1511(10586)開始加入中間層Visual layer的方式可以讓某些Graphic layer的特效以及繪圖能力能夠提升到讓Framework layer也能較為簡單操作的模式! 而XAML的 Visual Tree和 Composition的Visual tree是完全不相同的!
但是XAML的UI contorl可以和Composition的Visual tree互動之後系列文章會提及~XAML本身在建構Control是非常方便的但能互動的效果大多都是Transition為主,而XAML本身封裝了較多的功能(GPU的Render以及VisualState的實作)所以相較Visual layer來說較為肥大。
話不多說先來看看如何在非XAML的UWP APP下使用Composition八~
接者建立一個 Class MainEntry裡面只有Main()的方法!
public class MainEntry
{
public static void Main()
{
CoreApplication.Run(new CoreWindow());
}
}
基本上UWP跟其他應用程式都是可以透過Main進入執行狀態,只是專案範本( Template )本身很方便的幫忙建立App.xaml以及App.xaml.cs作為App的進入點。
移除掉了XAML的Page的方式就得使用CoreApplication.Run來執行APP,這邊我實作了一個Class名為CoreWindow。
public class CoreWindow : IFrameworkViewSource
{
public IFrameworkView CreateView()
{
return new CoreWindowView();
}
}
在CoreWindow裡面需要實作IFrameworkViewSource來提供應用程式做View的物件,這個Interface基本上就是UWP的Application view的Factory!接下來在實作另一物件 CoreWindowView
public class CoreWindowView : IFrameworkView
{
public void Initialize(CoreApplicationView applicationView)
{
}
public void Load(string entryPoint)
{
}
public void Run()
{
}
public void SetWindow(Windows.UI.Core.CoreWindow window)
{
}
private void CreateRectangle()
{
}
private void CreateBackgroundVisual()
{
}
private void InitializeComposition()
{
}
public void Uninitialize()
{
}
}
CoreWindowView實作了IFrameworkView的interface!這個interface提供View的生命週期( Live management )所以先會執行Initialize -> SetWindow -> Load -> Run -> Uninitialize這樣的流程。
接者可以在SetWindow來開刀!因為Initialize的時期並不會知道CoreApplication產生的Window是否會帶給這個View。所以SetWindow的Code如下
public void SetWindow(Windows.UI.Core.CoreWindow window)
{
coreWindow = window;
InitializeComposition();
CreateBackgroundVisual();
CreateRectangle();
}
接者開始是使用Composition API!
private void InitializeComposition()
{
compositor = new Compositor();
rootVisual = compositor.CreateContainerVisual();
compositionTarget = compositor.CreateTargetForCurrentView();
compositionTarget.Root = rootVisual;
}
先是建立Compositor,這個物件是所有Composition API 的Root所以之後的Composition都會使用到該物件為出發點! 這邊需要注意的是需要利用Compositor建立一個ContainerVisual 這個物件也就是所有visual的container!所以所有的visual都會被放入到這個container裡面~
然後需要再使用Compositor來建立View和Composition API的關係,因為Window以及View並非是由XAML提供得所以需要手動將關係建立起來!
接者來建立View的背景的顏色吧
private void CreateBackgroundVisual()
{
var backgroundVisual = compositor?.CreateSpriteVisual();
var backgroundBrush = compositor?.CreateColorBrush(Windows.UI.Colors.LightGray);
backgroundVisual.Brush = backgroundBrush;
backgroundVisual.Size = new Vector2((float)coreWindow.Bounds.Width, (float)coreWindow.Bounds.Height);
rootVisual?.Children.InsertAtBottom(backgroundVisual);
}
使用SpriteVisual這個簡單的API產生出Visual並且給上Brush以及Size之後在放入到container visual內,這邊使用到的Size都是使用向量!!!然後放到container visual的最後一個Children喔。
接者在來看看建立一個Rectangle在畫面上八
private void CreateRectangle()
{
var rectangle = compositor?.CreateSpriteVisual();
var rectangleBrush = compositor?.CreateColorBrush(Windows.UI.Colors.Red);
rectangle.Brush = rectangleBrush;
rectangle.Size = new Vector2(100, 100);
rectangle.Offset = new Vector3((float)coreWindow.Bounds.Width / 2.0f - rectangle.Size.X / 2.0f, (float)coreWindow.Bounds.Height / 2.0f - rectangle.Size.Y / 2.0f, 0);
rootVisual.Children.InsertAtTop(rectangle);
}
如上面的Code所示!建立一個Visual之後給上顏色、大小、偏移值然後在放到container visual內!
最後執行結果如下
可以發現到沒有使用到XAML的APP使用的記憶體使用量真的很少!而Composition所提供的功能真的是強大到不行所以很多動畫的都盡量交給Composition API來完成八~
***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio版本有所調整!***
參考資料 MSDN
下次再分享Windows 10 的新技術拉~