Nokia 最近發布兩款6寸大屏手機:Lumia 1520 和 Lumia 1320。為了支持這種設備 WP 升級了操作系統GDR3 支持了 1080P 的高清分辨率(1520),雖然GER3 是提供了向下兼容的,當然 GDR3 同時支持一些特性來支持 1080P 高清屏幕。
一下所有的討論的代碼實現都在 這里
Windows Phone 7 開始實現了統一分辨率規范 WVGA ( 800 x 480 ),一般適用與 3.7 - 4.3 寸屏。 在 Windows Phone 8 擴展支持了多種分辨率(3種) WVGA,WXGA(768 x 1280),和 720P(720 x 1280),但是他們支持的物理尺寸多數是在 4 – 4.5寸之間,並且無論應用運行在何種分辨率的機器上我們都是從基礎分辨率(800 x 480)進行適配,例如 720P 分辨率,屏幕的寬高比是 16:9,它會從基礎分辨率進行1.5倍的放大,但是由於寬高比的原因,實際縮放前的分辨率是 480 x 853,高度多出53個像素來適應 720P 的分辨率。 另外 768 x 1280 和基礎分辨率的屏幕寬高比都是 15:9 的所以可以直接進行一個 1.6 的屏幕縮放即可。
隨着 Windows Phone 8 的 GDR3 的發布,不僅有一個(1920 x 1080)高清分辨率的加入,同樣隨之帶來一些和大屏是手機兼容性的問題。例如一個相同頁面在 3.7 寸屏幕上顯示和在一個 6寸設備上顯示的不同效果,和用戶體驗。
理論上講,Windows Phone 也許會運行在更大(7“)屏的設備上,所以我們在需要的時候充分的利用屏幕,至少要在應用中知道我們當前是在何種分辨率的設備中,但是如果我們什么都不做的情況下系統會幫我們進行一個 720P 的應用適配(為了兼容現有應用),也就是從480 x 853進行縮放,但是他不是簡單的從 720P 縮放到 1080P,系統會從新渲染所有控件顯示到 1080P 設備上。
所以我們現有的App 可以繼續運行在 1080P 的設備上且不會收到影響,但是針對一個新應用我們怎么做才能更好的適配一個1080P的設備呢?例如:檢測到當前設備是支持1080P的時候我們播放的視頻進行一個適配,所以在GDR3 SDK支持一對新的可偵測屬性參數。PhysicalScreenResolution 和 RawDpiX
public partial class BasicInfo : PhoneApplicationPage { public BasicInfo() { InitializeComponent(); } string GetBasicScreenInfo() { var width = App.Current.Host.Content.ActualWidth; var height = App.Current.Host.Content.ActualHeight; var scaleFactor = (double)App.Current.Host.Content.ScaleFactor / 100d; return String.Format("{0} x {1}; {2:0.0} scale factor", width, height, scaleFactor); } string GetExtendedScreenInfo() { object temp; if (!DeviceExtendedProperties.TryGetValue("PhysicalScreenResolution", out temp)) return "not available, sorry"; var screenResolution = (Size)temp; // Can query for RawDpiY as well, but it will be the same value if (!DeviceExtendedProperties.TryGetValue("RawDpiX", out temp) || (double)temp == 0d) return "not available, sorry"; var dpi = (double)temp; var screenDiagonal = Math.Sqrt(Math.Pow(screenResolution.Width / dpi, 2) + Math.Pow(screenResolution.Height / dpi, 2)); var width = App.Current.Host.Content.ActualWidth; return String.Format("{0} x {1}; {2:0.0#} raw scale; {3:0.0}\"", screenResolution.Width, screenResolution.Height, screenResolution.Width / width, screenDiagonal); } void GetScreenInfoClick(object sender, RoutedEventArgs e) { basicScreenInfoOutput.Text = GetBasicScreenInfo(); extendedScreenInfoOutput.Text = GetExtendedScreenInfo(); } } }
例如 在GDR3 Lumia 920 中運行以上代碼的效果:
在 720P 模擬器中運行的效果(沒有GDR3的更新):
在6寸設備上運行效果,(基礎信息和 720P相同):
但是我們可以獲取到一些實際的數值來幫助開發者更好的適配自己的應用。
ZoomBox control
在上面提到的代碼示例中有一個叫做 ZoomBox的控件,類似於ViewBox,但是ViewBox可以讓內部控件比他本身更大,但是你可以結合 DisplayInformationEx使用,可以更好的適應屏幕。(這里使用了一個滑塊 slider 來調整控件區域的大小)
細心的同學可以看到隨着滑塊的滑動 文字/圖片/控件 大小的變化(文字可以自動換行),實際上我們可以在這里使用任何縮放的數值,來根據實際的屏幕尺寸。
Rendering size – aware content
正如前面說到的不論我們在何種分辨率下進行開發我們在 XAML 中都是用 800*480 這基礎分辨率下進行的設計。但是會有這樣的一種情況出現,一個4.5寸設備分辨率是480pixels,如果相同的分辨率到一個6寸的設備上那就相當於每一個像素都放大了33%,實際大小就相當於原有的638px的大小。DisplayInformationEx 可以計算這些數值並且配合縮放來使得控件大小看上去一致。
名稱解析:
Raw Pixels : 原始像素值 = 實際硬件上的像素數量,例如1080P的設備橫向擁有1080個像素點。
Host Pixels:設計/基礎 像素 = 在我們設計應用的時候 xaml runtime 提供的像素數,例如所以設備的基數像素點都是480pixels。
View Pixels:顯示像素 = 通過DisplayInformationEx 計算適配后 ZoomBox顯示出來的像素數,同時和機器的屏幕物理尺寸相關。
有一種情況 例如 Nokia Lumia 820(4.3”) 它的Raw Pixels,Host Pixels,以及 View Pixels 都是相同的。但是在更高分辨率的機器上就會不同了。
示例中的代碼是使用 ZoomBox在 Lumia 920中顯示一個硬幣保持硬幣的直徑在 0.75“。
在上面的這張圖中看到 通過ZoomBox的修正,讓 155px的 硬幣在1.6倍放大的屏幕上(4.5”)表現出與原始大小相符的圖片。
另外看一下在 6寸屏幕上顯示的效果:
對比一下 lumia 920 和 6寸設備顯示的效果。
ZoomBox 和 DisplayInformationEx 的使用方法
<screenSizeSupport:ZoomBox ZoomFactor="{Binding DisplayInformationEx.ViewPixelsPerHostPixel, Source={StaticResource DisplayInformationEmulator}}"> <StackPanel> <Image Source="/Assets/one_cent.png" Width="155" x:Name="scaledPenny"/> <TextBlock Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap" Text="computed size (0.75")" /> </StackPanel> </screenSizeSupport:ZoomBox>
And the code to render the penny:
const double sizeOfUsPenny = 0.75; private void ResizePenny() { var width = App.DisplayInformationEmulator.DisplayInformationEx .GetViewPixelsForPhysicalSize(sizeOfUsPenny); scaledPenny.Width = width; }
DisplayInformationEx and DisplayInformationEmulator
代碼中用到的DisplayInformationEx 可以看做是從 DisplayInformation class 中擴展出來的一些屬性 來幫助我們得到設備的一些物理設備屬性。
注意多數信息都是要在GDR3下才可以使用。
為了使用方便推薦將DisplayInformationEmulator添加到系統級資源中,並且支持數據綁定。
<Application.Resources>
<screenSizeSupport:DisplayInformationEmulator x:Key="DisplayInformationEmulator"/>
</Application.Resources>
代碼示例中提供了兩周訪問 DisplayInformationEmulator 的方法 使用開始畫面中的 view & change emulated size 或者使用屏幕右上角的 change display size 的圖標,然后在 new display values 中選擇不同的手機分辨率來模擬不同手機出現的效果。
如果你想固定在一種屏幕尺寸下進行調試可以直接修改 EmulatedScreenInfo="6.5,1080,1.778" 屬性。
例如:
<screenSizeSupport:DisplayInformationEmulator x:Key="DisplayInformationEmulator"
EmulatedScreenInfo="6.5,1080,1.778"/>
以上是在 GDR3 在 1080P 高清屏幕上開發應用的一些技巧分享給大家:)
歡迎大家在這里和我溝通交流或者在新浪微博上 @王博_Nick