生活随笔
收集整理的這篇文章主要介紹了
第十三章:位图(五)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
瀏覽和等待
ImageBrowser程序演示了Image的另一個功能,它允許您瀏覽本書中某些示例所使用的庫存照片。 正如您在下面的XAML文件中看到的那樣,Image元素與Label和兩個Button視圖共享屏幕。 請注意,在Image上設置了PropertyChanged處理程序。 您在第11章“可綁定基礎結構”中了解到,PropertyChanged處理程序由BindableObject實現,并在綁定屬性更改值時觸發。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="ImageBrowser.ImageBrowserPage"><ContentPage.Padding><OnPlatform x:TypeArguments="Thickness"iOS="0, 20, 0, 0" /></ContentPage.Padding><StackLayout><Image x:Name="image"VerticalOptions="CenterAndExpand"PropertyChanged="OnImagePropertyChanged" /><Label x:Name="filenameLabel"HorizontalOptions="Center" /><ActivityIndicator x:Name="activityIndicator" /><StackLayout Orientation="Horizontal"><Button x:Name="prevButton"Text="Previous"IsEnabled="false"HorizontalOptions="CenterAndExpand"Clicked="OnPreviousButtonClicked" /><Button x:Name="nextButton"Text="Next"IsEnabled="false"HorizontalOptions="CenterAndExpand"Clicked="OnNextButtonClicked" /></StackLayout></StackLayout>
</ContentPage>
此頁面上還有一個ActivityIndicator。 當程序等待長操作完成(例如下載位圖)但通常無法提供有關操作進度的任何信息時,通常會使用此元素。 如果您的程序知道操作的完成部分,則可以使用ProgressBar。 (ProgressBar將在下一章演示。)
ActivityIndi??cator有一個名為IsRunning的布爾屬性。通常,該財產是
false,ActivityIndi??cator不可見。將該屬性設置為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對象:
public partial class ImageBrowserPage : ContentPage
{[DataContract]class ImageList{[DataMember(Name = "photos")]public List<string> Photos = null;}WebRequest request;ImageList imageList;int imageListIndex = 0;public ImageBrowserPage(){InitializeComponent();// Get list of stock photos.Uri uri = new Uri("https://developer.xamarin.com/demo/stock.json");request = WebRequest.Create(uri);request.BeginGetResponse(WebRequestCallback, null);}void WebRequestCallback(IAsyncResult result){Device.BeginInvokeOnMainThread(() =>{try{Stream stream = request.EndGetResponse(result).GetResponseStream();// Deserialize the JSON into imageList;var jsonSerializer = new DataContractJsonSerializer(typeof(ImageList));imageList = (ImageList)jsonSerializer.ReadObject(stream);if (imageList.Photos.Count > 0)FetchPhoto();}catch (Exception exc){filenameLabel.Text = exc.Message;}});}void OnPreviousButtonClicked(object sender, EventArgs args){imageListIndex--;FetchPhoto();}void OnNextButtonClicked(object sender, EventArgs args){imageListIndex++;FetchPhoto();}void FetchPhoto(){// Prepare for new image.image.Source = null;string url = imageList.Photos[imageListIndex];// Set the filename.filenameLabel.Text = url.Substring(url.LastIndexOf('/') + 1);// Create the UriImageSource.UriImageSource imageSource = new UriImageSource{Uri = new Uri(url + "?Width=1080"),CacheValidity = TimeSpan.FromDays(30)};// Set the Image source.image.Source = imageSource;// Enable or disable buttons.prevButton.IsEnabled = imageListIndex > 0;nextButton.IsEnabled = imageListIndex < imageList.Photos.Count - 1;}void OnImagePropertyChanged(object sender, PropertyChangedEventArgs args){if (args.PropertyName == "IsLoading"){activityIndicator.IsRunning = ((Image)sender).IsLoading;}}
}
WebRequestCallback方法的整個主體都包含在lambda函數中,該函數是Device.BeginInvokeOnMainThread方法的參數。 WebRequest下載由輔助執行線程中的URI引用的文件。這可以確保操作不會阻止正在處理用戶界面的程序的主線程。回調方法也在此輔助線程中執行。但是,可以訪問Xamarin.Forms應用程序中的用戶界面對象
僅來自主線程。
Device.BeginInvokeOnMainThread方法的目的是解決此問題。此方法的參數排隊等待在程序的主線程中運行,并可以安全地訪問用戶界面對象。
當您單擊這兩個按鈕時,對FetchPhoto的調用使用UriImageSource來下載新位圖。這可能需要一秒鐘左右。 Image類定義一個名為IsLoading的Boolean屬性,當Image處于加載(或下載)位圖的過程中時,該屬性為true。 IsLoading由可綁定屬性IsLoadingProperty支持。這也意味著每當IsLoading更改值時,都會觸發PropertyChanged事件。該程序使用PropertyChanged事件處理程序 - 類的最底部的OnImagePropertyChanged方法 - 將ActivityIndi??cator的IsRunning prop.erty設置為與Image的IsLoading屬性相同的值。
您將在第16章“數據綁定”中看到,您的應用程序如何鏈接IsLoading和IsRunning等屬性,以便它們在沒有任何顯式事件處理程序的情況下保持相同的值。
這是ImageBrowser的實際應用:
某些圖像設置了EXIF方向標志,如果特定平臺忽略該標志,則圖像會側向顯示。
如果以橫向模式運行此程序,您將發現按鈕消失。 這個程序的更好的布局選項是Grid,第17章對此進行了演示。
總結
以上是生活随笔為你收集整理的第十三章:位图(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。