在開始我的分享之前呢,讓我先問下我的問題:
1、最近更新了Xamarin 4.1.1.3,我想問下版本更新信息在哪里看?
2、更新后我新建的項目沒有UWP項目了(雖然沒有用過,但是我想確認是4.1.1.3移除了還是我自身的問題),其實我覺得移除了也好,UWP就用UWP寫最好了!
3、我的模擬器無法使用,是我安裝的問題還是說有其他的設置?
再吐個槽:
1、Xamarin.Froms早已經更新到了2.3了,但是vs的模板一直沒更新(還是說可以其他設置更新?還是說2.3不穩定?),導致新建的項目的Froms版本依然是2.0的。
2、F7和F12功能不好用。
3、還是沒有預覽這個老生常談的問題。
我記得我還有幾個的,咋想不起了。。。好吧,算了,不想了。
還是那句話,有錯請留言指正,謝謝!
繼續正文,顯示圖片用的是Image這個倒是沒什么說的,設置圖片源的是通過Image的ImageSource類型的Source屬性來設置的,ImageSource類定義了四個靜態方法,一邊使用:
1、ImageSource.FromUri 用於訪問web的位圖
2、ImageSource.FromResource 訪問PCL中嵌入的資源的位圖
3、ImageSource.FromFile 訪問平台中的位圖
4、ImageSource.FromStream 通過Stream流加載位圖
要提醒的是“嵌入的資源”,如果你把圖片放入PCL中,並且想要訪問它,必須把圖片的生成操作改成“嵌入的資源”,如下:
ImageSource除了有四個靜態方法之外還有三個派生類:UriImageSource,FileImageSource,StreamImageSource。通過名字你可以跟上面的ImageSource的靜態方法找到對應,其中UriImageSource你就可以在XAML中直接設置Image的源了,而不必在Code-Bhind中去書寫:
<Image> <Image.Source> <UriImageSource Uri="http://hpimges.blob.core.chinacloudapi.cn/coverstory/watermark_zanzibarredcolobus_zh-cn11792109900_1920x1080.jpg" /> </Image.Source> </Image>
但是你會發現派生類有三個,靜態方法有四個,沒有ImageSource.FromResource的對應的派生類,豈不是說我們就不能在XAML中直接訪問PCL的嵌入資源了?答案當然是NO,需要我們自己寫一個。
在項目中新建一個ImageResourceExtension的類,這個類需要繼承IMarkupExtension接口(多的不說,自己F12去查看),
代碼如下:
namespace App1.Extension { [ContentProperty("Source")] public class ImageResourceExtension : IMarkupExtension { public string Source { get; set; } public object ProvideValue(IServiceProvider serviceProvider) { if (null == Source) return null; return ImageSource.FromResource(Source); } } //這個是我測試下IMarkupExtension的簡單用法弄得一個 [ContentProperty("TextColor")] public class LabelTextColorExtension : IMarkupExtension { public object ProvideValue(IServiceProvider serviceProvider) { return Color.Blue; } } }
然后我們就可以咋XAML直接設置PCL的嵌入的資源給Image了
<Image Source="{img:ImageResource App1.Images.logo_small.gif}" />
別忘了命名空間的引用:
xmlns:img="clr-namespace:App1.Extension"
對於嵌入的資源的訪問,唯一要說的就是其路徑,必須從程序集寫起,還有這個ImageResourceExtension類不能提到公共的當中,因為這是通過反射來獲取,如果你把圖片放到當前的PCL中,但是方法在公共的里面,那么你懂的反射的路徑是不對的,也就獲取不到圖片,但是也就是說如果圖片是公共的,放在公共的項目中,也就能能正常訪問了?卧槽,明天試試!
繼續Iamge的內容,訪問web的資源位圖,通過ImageSource的Uri相關的擴展或者使用ImageSource.FromStream都行,但是建議使用UriImageSource派生類,因為他可以把圖片緩存在程序的私有領域中,我們可以通過bool型的CachingEnabled和TimeSpan類型的CachingValidity來設置圖片的是否緩存和緩存時間。如果使用其他的則需要自己寫緩存的邏輯代碼。
位圖在Image中的填充則是通過枚舉的Aspect屬性來設置的,圖片填充這個應該沒有太多的說到的,我就簡單說下:
1、AspectFit — 默認的,這個就是保持圖片的比例填充Image。
2、Fill — 這個看意思也知道就是不考慮比例,填充整個Image。
3、AspectFill — 這個就是保持圖片的原始大小,但是只顯示Image能顯示的地方,簡單說就是如果圖片太大,就剪切Image那么大的一塊就行顯示。也就是說這個屬性對太大的圖片有影響。
關於位圖的顯示大小的問題,電子書中寫的媽的“拗口”的很,看了半天最后直接實踐,一個一個屬性的去調,才發現so easy,也難為別個寫書的了,當然也許是英文,語言溝通的原因。最終其實就是圖片在屏幕也就是用戶界面上的呈現是受Aspect屬性、Iamge元素的大小和位圖的大小的影響的。其限制影響大小如下:
Image的大小>位圖的大小>Aspect
雖然這三個的關系這么寫牛頭不對馬嘴,但是大意是這個。在簡單說就是自己去試,就是如下圖所示的標紅線的三類屬性的變換,要注意的就是VerticalOptions和HorizontalOptions屬性:
到這里你以為就完了,錯了!畢竟是跨平台的要想在多個平台上呈現的效果一致,那么你需要:
Although the pictures don’t look bad on any of the platforms, getting them all about the same size would require starting out with larger bitmaps.
也許這里就一句話,沒有前言后語的,不太容易理解,其實就是由於設備的原因Nokia的跟IOS和Android的像素的映射不一樣的原因的,如果讓他們“自由”的顯示,有較大的差異(),所以解決之法就是找個大一點的圖片然后設置他的寬和高(我不知道這個對不對啊,反正回了兩邊,也就只能理解到這兒了!)。
從Stream中讀取圖片,則需要ImageSource.FromStream或者StreamImageSource,雖然他們都是從劉總獲取圖片,但是並沒有什么需要特別說的。就直接上代碼了:
string resourceID = "App1.Images.logo_small.gif";
image1.Source = ImageSource.FromStream(() => { Assembly assembly = GetType().GetTypeInfo().Assembly; Stream stream = assembly.GetManifestResourceStream(resourceID); return stream; });
就到這里了!