博客园客户端UAP开发随笔 -- 适配不同尺寸的屏幕
Windows 8誕生之初,Modern apps被設(shè)計(jì)在運(yùn)行于全屏模式下。為了讓W(xué)indows在運(yùn)行Modern app時(shí)繼續(xù)擁有前臺(tái)多任務(wù)能力,Windows引入了一種全新的分屏技術(shù)“SnapView”。它允許將支持這種視圖的Modern app貼在屏幕一邊,以1/4 (實(shí)際上是邏輯分辨率寬度333左右)屏幕尺寸運(yùn)行。這種視圖特別適于工具類應(yīng)用(如詞典)和即時(shí)通訊類應(yīng)用(如QQ)。分屏多任務(wù)也成了Windows 8區(qū)別于iPad和安卓Pad系統(tǒng)的重要特征。
當(dāng)時(shí)程序員在考慮Modern App適配不同視圖和屏幕分辨率時(shí),一般主要考慮Landscape View (FullScreenSize, Fill)、Portriat View和SnapView,以及一些常見的分辨率如1366*768、1920*1080等。
可能是Windows的開發(fā)者們覺得僅僅是SnapView還不夠,也可能是再次感悟到“Windows”的真諦,自Windows 10開始,Modern app允許以窗口形式運(yùn)行。因此Modern app的窗口幾乎可以是任何尺寸,Windows Store App的顯示適配問題就需要再次拿出來(lái)聊聊了。
一般來(lái)說,Modern app尺寸變化的判斷和適配有以下4個(gè)時(shí)機(jī):
· VisualStateManager
· DetermineVisualState
· Window.SizeChanged
· OnApplyTheme
1. VisualStateManger 是最常用的方法,也是最方便的方法。它的用法也相對(duì)簡(jiǎn)單。先看一段XAML代碼:
<Page> <Grid x:Name=”LayoutGrid”> <VisualStateManager.VisualStateGroups><!-- Visual states reflect the application's view state inside the FlipView --><VisualStateGroup><VisualState x:Name="FullScreenLandscape"/><VisualState x:Name="Filled"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetName="AutoCompleteContainer" Storyboard.TargetProperty="Width"><DiscreteObjectKeyFrame KeyTime="0" Value="800"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="FullScreenPortrait"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetName="SP_Main" Storyboard.TargetProperty="Orientation"><DiscreteObjectKeyFrame KeyTime="0" Value="Vertical"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="Snapped"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetName="NavigationBarContainer" Storyboard.TargetProperty="Visibility"><DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetName="SV_Main" Storyboard.TargetProperty="Style"><DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource VerticalScrollViewerStyle}"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetName="SP_Main" Storyboard.TargetProperty="Orientation"><DiscreteObjectKeyFrame KeyTime="0" Value="Vertical"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetName="searchBarControl" Storyboard.TargetProperty="Margin"><DiscreteObjectKeyFrame KeyTime="0" Value="10,0,10,0"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetName="searchBarControl" Storyboard.TargetProperty="Width"><DiscreteObjectKeyFrame KeyTime="0" Value="300"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups> </Grid> </Page>VisualStateManager代碼位于Page的LayoutGrid下,以Storageboard的形式給出了不同視圖下需要做的適配性變化。以“SnapView”為例,我們通常給予SnapView更多關(guān)照,如container寬度的調(diào)整,ScrollView方向的調(diào)整,一些輔助的顯示控件的隱藏等等。值得欣慰的是,使用VisualStateManager的XAML代碼,你只需要考慮怎么來(lái)的,不需要考慮怎么回去。當(dāng)VisualState發(fā)生變化時(shí),StateManager會(huì)先讓視圖回到初始狀態(tài),然后再執(zhí)行新的變化。
必應(yīng)詞典的SnapView就是用這種方式實(shí)現(xiàn)的:
2. DetermineVisualState
DetermineVisualState像是VisualStateManager的C#版本,它是一個(gè)重載函數(shù),用于繼承了LayoutAwarePage的Page。來(lái)看一段代碼:
protected override string DetermineVisualState(ApplicationViewState viewState){if (viewState == ApplicationViewState.Snapped){if (_DefinitionControl != null){_DefinitionControl.SetToSnapStyle();}Grid_Layout.RowDefinitions[0].Height = new GridLength(60); …… ……}else{if (_DefinitionControl != null){_DefinitionControl.SetToLandscapeStyle();}Grid_Layout.RowDefinitions[0].Height = new GridLength(80);// semanticZoom.IsZoomOutButtonEnabled = true; } ……. ……return viewState.ToString();}在DetermineVisualState中,可以手動(dòng)添加一些代碼,做一些特殊處理,或者用VisualStateManager不容易表達(dá)的變化。但DetermineVisualState用起來(lái)就沒有VisualStateManager那么方便了,要知道怎么來(lái)的,還要知道怎么回去。這里的代碼應(yīng)該盡可能的少一些。
3. Window.Current.SizeChanged
如果想更精細(xì)的控制窗口變化時(shí)的界面效果,可以抓住在Window. Current .SizeChanged這個(gè)時(shí)機(jī):
protected override void OnNavigatedTo(NavigationEventArgs e) {Window.Current.SizeChanged += Current_SizeChanged; } Protected override void OnNavigatedFrom(NavigationeventArgs e) {Window.Current.SizeChanged-=Current_SizeChanged; }void Current_SizeChanged(object sender, WindowSizeChangedEventArgs e) { //do something here }4. OnApplyTheme
在自定義控件顯示前,OnApplyTheme是一個(gè)比較常用的函數(shù)用來(lái)靈活的給頁(yè)面元素賦值、修改控件外觀。舉個(gè)”栗“子:
protected override void OnApplyTemplate(){Grid layoutGrid = GetTemplateChild("Grid_Layout") as Grid;if (_counter % 2 == 0)layoutGrid.Background = Application.Current.Resources["HomepageDataContainerBackground1"] as SolidColorBrush;elselayoutGrid.Background = Application.Current.Resources["HomepageDataContainerBackground2"] as SolidColorBrush;StackPanel SP_KeyWords = GetTemplateChild("SP_KeyWords") as StackPanel;int counter = 1;foreach (KeyWord keyWord in _DailyNews.KeyWords){KeyWordTile keyWordTile = new KeyWordTile(keyWord, counter);keyWordTile.KeyWordClicked += dailyNewsTile_KeyWordTileClicked;SP_KeyWords.Children.Add(keyWordTile);counter++;} …. Do other things.base.OnApplyTemplate();}掌握了以上四點(diǎn),相信大家都能做出看起來(lái)很美、適配廣泛的的Modern App。
分享代碼,改變世界!
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
?
總結(jié)
以上是生活随笔為你收集整理的博客园客户端UAP开发随笔 -- 适配不同尺寸的屏幕的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jqGrid编辑—公共规则【附视频、pp
- 下一篇: SJTU OJ 3046 足球 题解