Xamarin.Forms Views介紹(四)

BitMap表示一個(gè)位圖文件,支持“JPEG, PNG, GIF, and BMP”所有圖片類型。Image不支持Gif圖片顯示。

Image屬性

  • Aspect :Aspect枚舉類型,設(shè)置Image的縮放模式。

    Fill - 拉伸圖片填充整個(gè)顯示區(qū)域,可能會(huì)導(dǎo)致圖像失真.
    AspectFill -剪切圖片填充整個(gè)區(qū)域,不會(huì)使圖像失真.
    AspectFit - 不對圖像進(jìn)行拉伸和剪切處理,根據(jù)圖像的大小上下或左右留白顯示,默認(rèn)值.

不同平臺縮放效果可能會(huì)有所不同

  • IsLoading :bool類型,表示圖片的加載狀態(tài)。
  • IsOpaque :bool類型,設(shè)置Image是否透明。
  • Source :ImageSource類型,設(shè)置顯示的圖片資源。

ImageSource介紹

ImageSource提供了四個(gè)靜態(tài)方法來創(chuàng)建對象。

  • FromUri :根據(jù)網(wǎng)絡(luò)圖片資源創(chuàng)建對象。
  • FromResource :根據(jù)嵌入到PCL的圖片資源創(chuàng)建對象。
  • FromFile :根據(jù)各個(gè)平臺提供的圖片資源創(chuàng)建對象。
  • FromStream :根據(jù).NET Stream創(chuàng)建對象。

Xamarin.Forms 提供了三個(gè)ImageSource的子類。

  • UriImageSource :表示網(wǎng)絡(luò)圖片資源,對應(yīng)FromUri。
  • FileImageSource :表示平臺相關(guān)圖片資源,對應(yīng)FromFile。
  • StreamImageSource :表示流圖片資源,對應(yīng)FromStream。

在XAML中定義ImageSource使用提供的ImageSource子類更方便,在代碼中定義使用提供的靜態(tài)方法更方便,靜態(tài)方法內(nèi)部實(shí)現(xiàn)就是返回系統(tǒng)提供的子類。


訪問網(wǎng)絡(luò)圖片資源

FromUri代碼示范:

Image image = new Image()
{
    Source = ImageSource.FromUri(new Uri("http://cdn-qn0.jianshu.io/assets/apple-touch-icons/72-feca4b183b9d29fd188665785dc7a7f1.png"))
};

也可以直接設(shè)置Image的Source為string或Uri類型地址,會(huì)隱式轉(zhuǎn)換為ImageSource。

Image image = new Image()
{
    Source = "http://cdn-qn0.jianshu.io/assets/apple-touch-icons/72-feca4b183b9d29fd188665785dc7a7f1.png"
};

對應(yīng)XAML為:

<Image Source="http://cdn-qn0.jianshu.io/assets/apple-touch-icons/72-feca4b183b9d29fd188665785dc7a7f1.png"/> 

XAML定義UriImageSource示范:

<Image HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="200" HeightRequest="200" Aspect="Fill">
    <Image.Source>
        <UriImageSource Uri="http://cdn-qn0.jianshu.io/assets/apple-touch-icons/72-feca4b183b9d29fd188665785dc7a7f1.png"/>
    </Image.Source>
</Image>

UriImageSource定義了CachingEnabledCachingValidity連個(gè)屬性。CachingEnabled表示是否啟用緩存,bool類型默認(rèn)為true。CachingValidity表示緩存的有效時(shí)間,TimeSpan類型,默認(rèn)為1天。

訪問嵌入到PCL圖片資源

圖片資源添加到PCL項(xiàng)目中,設(shè)置圖片的Build ActionEmbeddedResource。

資源嵌入到項(xiàng)目中會(huì)有一個(gè)對應(yīng)的資源ID,對應(yīng)的資源ID為程序集名.文件夾(若果有).圖片全名(包含擴(kuò)展名),如果不能確定資源ID可以調(diào)用Assembly 對象的GetManifestResourceNames方法,返回一個(gè)string類型數(shù)組,表示項(xiàng)目中所有資源的ID。更簡單的方法就是圖片資源右鍵屬性查看資源ID。

調(diào)用FromResource創(chuàng)建圖片資源

var imageResID = "views.image.image.png";
image.Source = ImageSource.FromResource(imageResID);

XAML中如何調(diào)用嵌入資源?如果你熟悉x:FactoryMethod使用,可能會(huì)想通過x:FactoryMethod調(diào)用ImageSource.FromResource方法,但是ImageSource.FromResource方法要求圖片資源與調(diào)用方法在同一個(gè)程序集內(nèi),通過x:FactoryMethod調(diào)用ImageSource.FromResource方法時(shí)調(diào)用代碼是在Xamarin.Forms.Xaml程序集內(nèi)的。

《Creating Mobile App with Xamarin.Forms》中介紹了解決方法,定義一個(gè)XAML擴(kuò)展標(biāo)記(先不多做介紹)。

[ContentProperty("Source")]
public class ResourceImageExtension : IMarkupExtension
{

    public string Source
    {
        get;
        set;
    }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        if (Source == null)
            return null;

        return ImageSource.FromResource(Source);
    }
}

定義了Source屬性表示圖片資源ID。添加ContentProperty特性,指定Source為ContentProperty,在使用ResourceImageExtension時(shí)不必明確指定“Source=”。

XAML中定義,local表示ResourceImageExtension所在命名空間

<Image x:Name="image" Source="{local:ResourceImageExtension views.image.image.png}"/>

訪問單獨(dú)平臺圖片資源

由于每個(gè)平臺對一些圖片有特別的分辨率要求,所以有時(shí)候會(huì)為每個(gè)平臺準(zhǔn)備不同大小圖片,ImageSource.FromFile靜態(tài)方法和相應(yīng)的FileImageSource類能方便訪問存儲(chǔ)在平臺項(xiàng)目中的圖片資源。

各平臺存儲(chǔ)圖片路徑:
iOS - 圖片存儲(chǔ)在Resources 目錄中并設(shè)置Build ActionBundleResource (提供@2x命名文件,相關(guān)分辨率知識不做介紹).
Android - 圖片存儲(chǔ)在Resources/drawable 目錄中并設(shè)置Build Action:AndroidResource. (不同分辨路圖片放在Resources下drawable-ldpidrawable-hdpi 等子目錄中 ).
Windows Phone - 圖片存儲(chǔ)在Assets目錄或其子目錄下并設(shè)置Build ActionContent .

示例代碼:

image.Source = new FileImageSource()
{
    File = Device.OnPlatform(iOS: "ios.png", Android: "android.png", WinPhone: "Assets/WindowsPhone.png")
};

對于iOS和Android直接指定文件名即可,這兩個(gè)平臺資源文件默認(rèn)存儲(chǔ)在Resources目錄中,Windows Phone對應(yīng)的路徑應(yīng)包含Assets目錄。

對應(yīng)的XAML為

<Image>
    <Image.Source>
        <OnPlatform x:TypeArguments="ImageSource" iOS="ios.png" Android="android.png" WinPhone="Assets/WindowsPhone.png" />
    </Image.Source>
</Image>

分別截取了Android和iOS模擬器的圖片,運(yùn)行起來效果有點(diǎn)怪。


iOS、Android運(yùn)行效果

通過Stream訪問圖片資源

通過Stream可以訪問網(wǎng)絡(luò)圖片和嵌入項(xiàng)目中的圖片資源。ImageSource.FromStream或者StreamImageSource可以幫助我們輕松的訪問Stream對應(yīng)的圖片資源。

FromStream方法的參數(shù)并不是Stream類型而是Func<Stream>類型(一個(gè)無參數(shù),返回值為Stream的方法)。

示例1——訪問本地嵌入圖片資源

var imageResID = "views.image.image.png";
image.Source = ImageSource.FromStream(() =>
{
    Assembly assembly = GetType().GetTypeInfo().Assembly;
    return assembly.GetManifestResourceStream(imageResID);
});

示例2——訪問網(wǎng)絡(luò)圖片資源

var request = WebRequest.Create(new Uri("http://img2.myhsw.cn/2015-12-29/q9z0b418.jpg"));
request.BeginGetResponse((IAsyncResult arg) =>
{
    var stream = request.EndGetResponse(arg).GetResponseStream();
    //Windows 平臺特殊處理
    if (Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows)
    {
        MemoryStream memStream = new MemoryStream();
        stream.CopyTo(memStream);
        memStream.Seek(0, SeekOrigin.Begin);
        stream = memStream;
    }

    var imageSource = ImageSource.FromStream(() => stream);
    Device.BeginInvokeOnMainThread(() => { image.Source = imageSource; });

}, null);

子線程中不允許更新UI,在子線程中更新UI借助Device.BeginInvokeOnMainThread方法完成。

不同平臺圖片顯示效果不同。
“On iOS and Android, the bitmap is displayed in its pixel size. In other words, the bitmap is rendered with a one-to-one mapping between the pixels of the bitmap and the pixels of the video display. The iPhone 6 simulator used for these screenshots has a screen width of 750 pixels, and you can see that the 256-pixel width of the bitmap is about one-third that width. The Android phone here is a Nexus 5, which has a pixel width of 1080, and the bitmap is about one-quarter that width.
On the Windows Runtime platforms, however, the bitmap is displayed in device-independent units—in this example, 256 device-independent units. The Nokia Lumia 925 used for these screenshots has a pixel width of 768, which is approximately the same as the iPhone 6. However, the screen width of this Windows 10 Mobile phone in device-independent units is 341, and you can see that the rendered bitmap is much wider than on the other platforms.”


Toolbar使用

Toolbar表示應(yīng)用程序的工具欄,iOS和AndroidToolbar顯示在屏幕頂部,Windows Phone顯示在屏幕底部。

Toolbar 不同平臺效果

Forms并沒有提供Toolbar類,為Page類的ToolbarItems集合賦值即可實(shí)現(xiàn)Toolbar效果。Windows Phone平臺ContentPage添加ToolbarItem正常顯示,Android和iOS平臺必須使用NavigationPage。

ToolbarItem并不View實(shí)現(xiàn)而是繼承MenuItem類,ToolbarItem定義了三個(gè)屬性。
Text - ToolbarItem顯示的文本。
Order - ToolbarItemOrder枚舉類型,決定ToolbarItem顯示圖標(biāo)(Primary)還是顯示文字(Secondary)。
Icon - FileImageSource類型,ToolbarItem顯示的圖標(biāo)。FileImageSource類型說明圖標(biāo)文件是單獨(dú)存儲(chǔ)在平臺項(xiàng)目中。

XAML示例代碼:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Item 1" Order="Primary" Clicked="響應(yīng)點(diǎn)擊事件">
        <ToolbarItem.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                            iOS="tc.png"
                            Android="tc.png"/>
        </ToolbarItem.Icon>
    </ToolbarItem>
    <ToolbarItem Text="Item 2" Order="Primary" >
        <ToolbarItem.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                            iOS="tf.png"
                            Android="tf.png"/>
        </ToolbarItem.Icon>
    </ToolbarItem>
    <ToolbarItem Text="Item 3" Order="Primary" >
        <ToolbarItem.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                            iOS="tg.png"
                            Android="tg.png"/>
        </ToolbarItem.Icon>
    </ToolbarItem>

    <ToolbarItem Text="Item 4" Order="Secondary" >
        <ToolbarItem.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                            iOS="tf.png"
                            Android="tf.png"/>
        </ToolbarItem.Icon>
    </ToolbarItem>
    <ToolbarItem Text="Item 5" Order="Secondary" >
        <ToolbarItem.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                            iOS="tg.png"
                            Android="tg.png"/>
        </ToolbarItem.Icon>
    </ToolbarItem>
        
</ContentPage.ToolbarItems>

一定要修改App.xaml.cs文件中構(gòu)造函數(shù)MainPage賦值的代碼為MainPage = new NavigationPage(new 自己的page類());

各平臺圖標(biāo)像素要求

Android ToolbarItem圖標(biāo)像素:
? drawable-mdpi (medium DPI) — 32 pixels square
? drawable-hdpi (high DPI) — 48 pixels square
? drawable-xhdpi (extra high DPI) — 64 pixels square
? drawable-xxhdpi (extra extra high DPI) — 96 pixels square

IOS ToolbarItem圖標(biāo)像素:
默認(rèn)為20像素正方形,應(yīng)提供@2x(40-pixel-square )和@3x(60-pixel-square )版本使iPhone5 和iPhone6有更好的顯示效果。

Windows Phone ToolbarItem圖標(biāo)像素要求:
大小為76像素的正方形圖標(biāo)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容