Xamarin.Forms學習之位圖(一)


  在開始我的分享之前呢,讓我先問下我的問題:

  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; });

 

 

  就到這里了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM