連載
» 2016年09月21日 05時00分 UPDATE

.NET TIPS:Xamarin.Forms:URLを指定して画像を表示するには?

Xamarin.FormsアプリではImageコントロールのSourceプロパティを使用することで、URLを指定して画像を表示できる。

[山本康彦,BluewaterSoft/Microsoft MVP for Windows Development]
「.NET TIPS」のインデックス

連載目次

対象:Visual Studio 2015以降


 Xamarin.Formsは、XAMLとC#を使ってAndroid/iOS/Windows向けのクロスプラットフォーム開発を行える開発環境だ。

 本稿では、Xamarin.FormsアプリでWebから画像を取得して表示する方法を解説する。

URLを指定して画像を表示するには?

 Imageコントロール(Xamarin.Forms名前空間)のSourceプロパティに、ImageSourceオブジェクト(Xamarin.Forms名前空間)をセットすればよい。ImageSourceオブジェクトの作り方には、いろいろなやり方がある。

 XAMLでは、次のコードのように書ける。

<!-- 簡単な書き方 -->
<Image Source="/ait/images/gyoumu_link_btn.gif" />

<!-- 冗長な書き方 -->
<Image>
  <Image.Source>
    <UriImageSource
        Uri="/ait/images/gyoumu_link_btn.gif" />
  </Image.Source>
</Image>

URLを指定して画像を表示する例(XAML)
普通は上のコードのようにシンプルに書けばよい。
下のようにSourceプロパティを<Image>要素の子要素として記述するときは、<ImageSource>要素ではなく<UriImageSource>要素を使う。

 上のXAMLコードの「冗長な書き方」を見てもらうと、ImageコントロールのSourceプロパティに(前述したImageSourceオブジェクトではなく)UriImageSourceオブジェクトを設定している。

 UriImageSourceクラスはImageSourceクラスを継承しており、Uriプロパティが追加されている。上のコードのようにURIを指定するだけで使えるのだ(ImageSourceクラスにはUriプロパティがないので、上のコードのような記述はできない)。

 コードビハインドでは、次のコードのように書ける。

// XAMLコード側には、「Image1」という名前のImageコントロールが配置してある

// 表示したい画像のURL
string url = "……省略……";

// 簡単な書き方
Image1.Source = ImageSource.FromUri(new Uri(url));

// UriImageSourceを使ってもよい
Image1.Source = new UriImageSource
                    {
                      CachingEnabled = true,
                      Uri = new Uri(url)
                    };

// 暗黙の型変換が働くので、次のようにURL文字列を直接与えてもよい
Image1.Source = url;

URLを指定して画像を表示する例(C#)
コードビハインドではImageSourceクラスのFromUriメソッドを使うと簡単だ。
UriImageSourceクラスを使ってもよいが、かえって冗長になる。
また、暗黙の型変換が働くので、URL文字列を直接与えてもよい。

 コードビハインドでは、ImageSourceクラスのFromUriメソッドを使うと簡単である。FromUriメソッドは、ImageSourceオブジェクトを返す。

 また、暗黙の型変換が用意されているので、上のコードの最後にあるように、URL文字列をImageコントロールのSourceプロパティに直接代入するコードも書ける。

 XAMLコードと同様にUriImageSourceクラスを使ってもよいが、ちょっと冗長になる。UriImageSourceクラスを使う場合にはキャッシュの制御ができる(ただし本稿執筆時点では、CachingEnabled=falseにすると例外になってしまった)。

 なお、ImageコントロールのSourceプロパティへの代入は、非同期に実行される。代入し終わってから、非同期にWebアクセスが実行されるのだ。そのWebアクセス中にはIsLoadingプロパティがtrueになる。それを利用して、画像が取得されるまでの間にプレースホルダーを表示することも可能だ(コード例は後述)。

実際の例

 実際の例として、以上で説明したコードを試してみよう。

 ソリューションを新しく作るときに[Blank Xaml App (Xamarin.Forms Portable)]を選ぶ。そのPCLプロジェクトにあるMainPage.xamlファイルの内容を次のように変更する。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:dotNetTips1159"
             x:Class="dotNetTips1159.MainPage">
  <!--<Label Text="Welcome to Xamarin Forms!"
           VerticalOptions="Center"
           HorizontalOptions="Center" />-->
  <ContentPage.Padding>
    <OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" />
  </ContentPage.Padding>
  <ContentPage.Resources>
    <ResourceDictionary>
      <Style TargetType="Image">
        <Setter Property="Aspect" Value="AspectFit" />
        <Setter Property="HeightRequest" Value="50" />
        <Setter Property="VerticalOptions" Value="StartAndExpand" />
      </Style>
      <Style TargetType="Label">
        <Setter Property="HorizontalOptions" Value="Center" />
        <Setter Property="VerticalOptions" Value="EndAndExpand" />
      </Style>
    </ResourceDictionary>
  </ContentPage.Resources>

  <StackLayout>
    <Label Text="Xamlで表示" />
    <Image Source="/ait/images/gyoumu_link_btn.gif" />
    <Label Text="コードで表示" />
    <Image x:Name="Image1" />
  </StackLayout>
</ContentPage>

URLを指定して画像を表示するサンプルコード(XAML)
自動生成されたLabelコントロールをコメントアウトし、<ContentPage.Padding>要素以降を追加した。
Imageコントロールを2つ配置し、前者にはURLを直接与えた。後者には「Image1」という名前だけを与えた(後ほど、コードビハインドからSourceプロパティをセットする)。

 次に、コードビハインドのMainPage.xaml.csファイルに次のようなコードを追加する。ここでは、Webアクセス中にプレースホルダーとしてImageコントロールの背景色を変えている。

public MainPage()
{
  InitializeComponent();

  string url = "/ait/subtop/features/"
               + "dotnet/images/dotnettips_index/title.png";
  SetImageAsync(url);
}

private async void SetImageAsync(string url)
{
  // Sourceプロパティへのセットは非同期に実行される
  Image1.Source = ImageSource.FromUri(new Uri(url));

  // プレースホルダーの表示
  await Task.Delay(300); // 300ミリ秒待って、
  if (Image1.IsLoading) // Webアクセス中だったら、
  {
    Image1.BackgroundColor = Color.Green; // Imageコントロールの背景色を緑にする
    while (Image1.IsLoading) // Webアクセスが続いている間は、
      await Task.Delay(100); // 100ミリ秒ずつ待機し、
    Image1.BackgroundColor = Color.Transparent; // 完了したら背景色を透明に戻す
  }
}

URLを指定して画像を表示するサンプルコード(C#)
MainPage.xaml.csファイルのコンストラクタに、「InitializeComponent();」より下の部分を追加した。また、新しくSetImageAsyncメソッドを追加した。

 上のコードのSetImageAsyncメソッドの中で、Webから画像を取得して表示している。さらに、Webアクセスしている間は、Imageコントロールの背景色を緑色に変えている。

 ImageコントロールのSourceプロパティへのセットは非同期に実行される。しかし、その後のコードでIsLoadingプロパティの監視をしようとすると、その部分は自前で非同期処理を書かねばならない。XamarinのC#もasync/await構文に対応しているので、上のコードのように簡単に書ける。

 これで実行してみると、次の画像のようになる。この画像では分からないが、下側のImageコントロールは画像が出てくるまで緑色になっている(初回実行時のみ。2回目以降はキャッシュから表示するので直ちに画像が出る)。

実行結果(Visual Studio Emulator for Android)
実行結果(iOS Simulator for Windows)
実行結果(Mobile Emulator) 実行結果
上はVisual Studio Emulator for Androidでの実行結果。中はiOS Simulator for Windowsでの実行結果。下はMobile Emulator(Windows 10)での実行結果。なお、iOS Simulator for Windowsは本稿執筆段階でプレビュー段階となっている。使用方法については「XamarinアプリのMacでのビルドとiOS Simulator for Windows」を参照されたい。

まとめ

 URLを指定してImageコントロールに画像を表示するには、XAMLコードではSource属性にURLを書くだけでよい。コードビハインドでも同様だが、IsLoadingプロパティを活用してプレースホルダーを表示したりできる。

「.NET TIPS」のインデックス

.NET TIPS

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。