Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2191011
  • 博文数量: 849
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8135
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
  • 认证徽章:
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(849)

文章存档

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(273)

2010年(1)

2009年(54)

2008年(66)

2007年(49)

2006年(82)

2005年(12)

分类: Android平台

2018-08-17 22:41:19

浏览和等待
ImageBrowser程序演示了Image的另一个功能,它允许您浏览本书中某些示例所使用的库存照片。 正如您在下面的XAML文件中看到的那样,Image元素与Label和两个Button视图共享屏幕。 请注意,在Image上设置了PropertyChanged处理程序。 您在第11章“可绑定基础结构”中了解到,PropertyChanged处理程序由BindableObject实现,并在绑定属性更改值时触发。

点击(此处)折叠或打开

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.              x:Class="ImageBrowser.ImageBrowserPage">
  4.  
  5.     <ContentPage.Padding>
  6.         <OnPlatform x:TypeArguments="Thickness"
  7.                     iOS="0, 20, 0, 0" />
  8.     </ContentPage.Padding>
  9.  
  10.     <StackLayout>
  11.         <Image x:Name="image"
  12.                VerticalOptions="CenterAndExpand"
  13.                PropertyChanged="OnImagePropertyChanged" />
  14.         <Label x:Name="filenameLabel"
  15.                HorizontalOptions="Center" />
  16.  
  17.         <ActivityIndicator x:Name="activityIndicator" />
  18.         <StackLayout Orientation="Horizontal">
  19.             <Button x:Name="prevButton"
  20.                     Text="Previous"
  21.                     IsEnabled="false"
  22.                     HorizontalOptions="CenterAndExpand"
  23.                     Clicked="OnPreviousButtonClicked" />
  24.             <Button x:Name="nextButton"
  25.                     Text="Next"
  26.                     IsEnabled="false"
  27.                     HorizontalOptions="CenterAndExpand"
  28.                     Clicked="OnNextButtonClicked" />
  29.         </StackLayout>
  30.     </StackLayout>
  31. </ContentPage>
此页面上还有一个ActivityIndicator。 当程序等待长操作完成(例如下载位图)但通常无法提供有关操作进度的任何信息时,通常会使用此元素。 如果您的程序知道操作的完成部分,则可以使用ProgressBar。 (ProgressBar将在下一章演示。)
ActivityIndicator有一个名为IsRunning的布尔属性。通常,该财产是
false,ActivityIndicator不可见。将该属性设置为true可使ActivityIn?dicator可见。所有这三个平台都实现了一个动画视觉,表明该程序正在运行,但在每个平台上看起来都有点不同。在iOS上它是一个旋转轮,在Android上它是一个旋转的部分圆圈。在Windows设备上,一系列点在屏幕上移动。
为了提供对库存图像的浏览访问,ImageBrowser需要下载包含所有文件名列表的JSON文件。多年来,各种版本的.NET引入了几个能够通过Web下载对象的类。但是,并非所有这些都可用于可移植类库中的.NET版本,该类库具有与Xamarin.Forms兼容的配置文件。可用的类是WebRequest及其后代类HttpWebRequest。
WebRequest.Create方法基于URI返回WebRequest方法。 (返回值实际上是一个HttpWebRequest对象。)BeginGetResponse方法需要一个回调函数,当引用URI的Stream可用于访问时,该函数被调用。通过调用EndGetResponse和GetResponseStream可以访问Stream。
一旦程序在以下代码中访问Stream对象,它就会使用DataCon?tractJsonSerializer类以及在ImageBrowserPage类顶部附近定义的嵌入式ImageList类,将JSON文件转换为ImageList对象:

点击(此处)折叠或打开

  1. public partial class ImageBrowserPage : ContentPage
  2. {
  3.     [DataContract]
  4.     class ImageList
  5.     {
  6.         [DataMember(Name = "photos")]
  7.         public List<string> Photos = null;
  8.     }
  9.     WebRequest request;
  10.     ImageList imageList;
  11.     int imageListIndex = 0;
  12.     public ImageBrowserPage()
  13.     {
  14.         InitializeComponent();
  15.         // Get list of stock photos.
  16.         Uri uri = new Uri("https://developer.xamarin.com/demo/stock.json");
  17.         request = WebRequest.Create(uri);
  18.         request.BeginGetResponse(WebRequestCallback, null);
  19.     }
  20.     void WebRequestCallback(IAsyncResult result)
  21.     {
  22.         Device.BeginInvokeOnMainThread(() =>
  23.         {
  24.             try
  25.             {
  26.                 Stream stream = request.EndGetResponse(result).GetResponseStream();
  27.                 // Deserialize the JSON into imageList;
  28.                 var jsonSerializer = new DataContractJsonSerializer(typeof(ImageList));
  29.                 imageList = (ImageList)jsonSerializer.ReadObject(stream);
  30.                 if (imageList.Photos.Count > 0)
  31.                     FetchPhoto();
  32.             }
  33.             catch (Exception exc)
  34.             {
  35.                 filenameLabel.Text = exc.Message;
  36.             }
  37.         });
  38.     }
  39.     void OnPreviousButtonClicked(object sender, EventArgs args)
  40.     {
  41.         imageListIndex--;
  42.         FetchPhoto();
  43.     }
  44.     void OnNextButtonClicked(object sender, EventArgs args)
  45.     {
  46.         imageListIndex++;
  47.         FetchPhoto();
  48.     }
  49.     void FetchPhoto()
  50.     {
  51.         // Prepare for new image.
  52.         image.Source = null;
  53.         string url = imageList.Photos[imageListIndex];
  54.         // Set the filename.
  55.         filenameLabel.Text = url.Substring(url.LastIndexOf('/') + 1);
  56.         // Create the UriImageSource.
  57.         UriImageSource imageSource = new UriImageSource
  58.         {
  59.             Uri = new Uri(url + "?Width=1080"),
  60.             CacheValidity = TimeSpan.FromDays(30)
  61.         };
  62.         // Set the Image source.
  63.         image.Source = imageSource;
  64.         // Enable or disable buttons.
  65.         prevButton.IsEnabled = imageListIndex > 0;
  66.         nextButton.IsEnabled = imageListIndex < imageList.Photos.Count - 1;
  67.     }
  68.     void OnImagePropertyChanged(object sender, PropertyChangedEventArgs args)
  69.     {
  70.         if (args.PropertyName == "IsLoading")
  71.         {
  72.             activityIndicator.IsRunning = ((Image)sender).IsLoading;
  73.         }
  74.     }
  75. }
WebRequestCallback方法的整个主体都包含在lambda函数中,该函数是Device.BeginInvokeOnMainThread方法的参数。 WebRequest下载由辅助执行线程中的URI引用的文件。这可以确保操作不会阻止正在处理用户界面的程序的主线程。回调方法也在此辅助线程中执行。但是,可以访问Xamarin.Forms应用程序中的用户界面对象
仅来自主线程。
Device.BeginInvokeOnMainThread方法的目的是解决此问题。此方法的参数排队等待在程序的主线程中运行,并可以安全地访问用户界面对象。
当您单击这两个按钮时,对FetchPhoto的调用使用UriImageSource来下载新位图。这可能需要一秒钟左右。 Image类定义一个名为IsLoading的Boolean属性,当Image处于加载(或下载)位图的过程中时,该属性为true。 IsLoading由可绑定属性IsLoadingProperty支持。这也意味着每当IsLoading更改值时,都会触发PropertyChanged事件。该程序使用PropertyChanged事件处理程序 - 类的最底部的OnImagePropertyChanged方法 - 将ActivityIndicator的IsRunning prop.erty设置为与Image的IsLoading属性相同的值。
您将在第16章“数据绑定”中看到,您的应用程序如何链接IsLoading和IsRunning等属性,以便它们在没有任何显式事件处理程序的情况下保持相同的值。
这是ImageBrowser的实际应用:

某些图像设置了EXIF方向标志,如果特定平台忽略该标志,则图像会侧向显示。
如果以横向模式运行此程序,您将发现按钮消失。 这个程序的更好的布局选项是Grid,第17章对此进行了演示。
阅读(71) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册