wp8.1 创建动态磁贴应用
目前Windows Phone 8.1所支持磁贴像素大小有71x71、150x150和310x150,分为大中小三种模式,对于桌面磁贴微软提供的诸多模板http://msdn.microsoft.com/zh-cn/library/windows/apps/hh761491.aspx,模板功能比较简单,就是图像和文字的结合,如果要实现复杂的磁贴组合,比较天气预报那样的磁贴,那就要微软RenderTargetBitmap类事先生成图像,再更新到磁贴。
我们写一个静态方法。在使用RenderTargetBitmap类的同时,建议去看一下微软的关于此类的用法,参数中的element元素也有所限制。
1.一些视频无法生成图像。
2.自定义一些第三方插件无法生成图像。
4.元素必须要在屏幕元素的视觉树中,比如动态创建一个元素,那么就无法生成该元素的图像,出现空白。建议预先将元素写在xaml中并设置opacity为0即可。
1 public static async System.Threading.Tasks.Task RenderImage(Windows.UI.Xaml.UIElement element, string filename) 2 { 3 Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap renderTargetBitmap = new Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap(); 4 await renderTargetBitmap.RenderAsync(element, (int)element.DesiredSize.Width, (int)element.DesiredSize.Height); 5 Windows.Storage.Streams.IBuffer pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); 6 var width = renderTargetBitmap.PixelWidth; 7 var height = renderTargetBitmap.PixelHeight; 8 9 Windows.Storage.StorageFile storageFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.ReplaceExisting); 10 using (var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)) 11 { 12 var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.JpegEncoderId, stream); 13 encoder.SetPixelData(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8, Windows.Graphics.Imaging.BitmapAlphaMode.Ignore, 14 (uint)width, (uint)height, 96, 96, pixelBuffer.ToArray()); 15 await encoder.FlushAsync(); 16 } 17 }
那么在xaml我们可以这样做。
1 <Grid Opacity="0"> 2 <Grid x:Name="Tile310x150f" Width="310" Height="150"> 3 <!--内容--> 4 </Grid> 5 <Grid x:Name="Tile310x150b" Width="310" Height="150"> 6 <!--内容--> 7 </Grid> 8 </Grid>
现在我们在后台来刷新图像。
1 public async Task RefreshImage() 2 { 3 Grid render310x150f = this.ViewControl.FindName("Tile310x150f") as Grid; 4 await Common.Common.RenderImage(render310x150f, "Tile310x150f.jpg"); 5 6 Grid render310x150b = this.ViewControl.FindName("Tile310x150b") as Grid; 7 await Common.Common.RenderImage(render310x150b, "Tile310x150b.jpg"); 8 }
然后pin到桌面。这里提醒一点,RefreshImage要在RequestCreateAsync前执行完成,因为当启用磁贴pin时,页面会跳转到桌面,否则会发生截图空白。
1 public async void PinTile(string tileId) 2 { 3 Uri uri = new Uri("ms-appdata:///local/Tile71x71f.jpg"); 4 Windows.UI.StartScreen.SecondaryTile tile = new Windows.UI.StartScreen.SecondaryTile(tileId, "123", "/MainPage.xaml", uri, Windows.UI.StartScreen.TileSize.Default); 5 tile.VisualElements.Wide310x150Logo = uri; 6 tile.DisplayName = " "; 7 8 await RefreshImage(); 9 10 this.isPin = await tile.RequestCreateAsync(); 11 this.PinVisible = Visibility.Collapsed; 12 this.UnpinVisible = Visibility.Visible; 13 14 this.UpdateTile(); 15 }
接下来是update tile的方法,这里的GetTemplateContent就是为了获取微软磁贴预制的模板,update其实是即时信息展示,并不是刻意为了磁贴动态的效果。
1 public void UpdateTile() 2 { 3 if (isPin) 4 { 5 var updator = Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForSecondaryTile(this.tileId); 6 updator.Clear(); 7 updator.EnableNotificationQueue(true); 8 9 var tile310x150f = Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(Windows.UI.Notifications.TileTemplateType.TileWide310x150Image); 10 var tile310x150b = Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(Windows.UI.Notifications.TileTemplateType.TileWide310x150Image); 11 12 var imageElement = tile310x150f.GetElementsByTagName("image")[0]; 13 imageElement.Attributes.GetNamedItem("src").NodeValue = "ms-appdata:///local/Tile310x150f.jpg"; 14 var notification = new Windows.UI.Notifications.TileNotification(tile310x150f); 15 updator.Update(notification); 16 17 imageElement = tile310x150b.GetElementsByTagName("image")[0]; 18 imageElement.Attributes.GetNamedItem("src").NodeValue = "ms-appdata:///local/Tile310x150b.jpg"; 19 notification = new Windows.UI.Notifications.TileNotification(tile310x150b); 20 updator.Update(notification); 21 } 22 }