この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
Xamarin.Formsの、ビューの1つであるImageは、画像を表示するためのコントロールです。
参考:Xamarin Developers Guide 「Working with Images」
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/images/
2 イメージの指定 Source
プロパティSource(ImageSource型)には、表示する画像を指定します。
指定の方法は、画像の配置場所によって次の3種類があります。
各プラットフォーム(ローカル) | 各プラットフォームのプロジェクトにリソースとして配置します。 |
インターネット | インターネット上に配置し、ダウンロードして使用します。 |
共有プロジェクト(ローカル) | 共有プロジェクト(PCL)にリソースとして配置します。 |
(1) 各プラットフォーム上に配置する場合
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
Content = new Image {
Source = "classmethod.png"
//この書き方でもOK
//Source = ImageSource.FromFile("classmethod.png")
//この書き方でもOK
//Source = FileImageSource.FromFile("classmethod.png")
};
}
}
Android | iOS | Windows Phone |
ローカルの画像ファイルは、Androidの場合は、Resources/Drawableの階層下、iOSの場合は、Resourcesの階層下に配置します。WindowsPhoneではカレントになりますが、特定のフォルダにまとめることも可能です。
なおコードは、PCL(一か所)で書けますが、画像ファイルは、プラットフォームごと(3か所)に置く必要があります。
Android | iOS | Windows Phone |
(2) インターネット上に配置する場合
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage{
class MyPage : ContentPage {
public MyPage() {
var uri = "http://www.sapporoworks.ne.jp/main.jpg";
Content = new Image {
Source = ImageSource.FromUri(new Uri(uri))
//この書き方でもOK
//Source = uri
//この書き方でもOK
//Source = new UriImageSource {
// Uri = new Uri(uri),
// CachingEnabled = false
//}
};
}
}
}
UriImageSourceには、キャッシュ機能があります。
Android | iOS | Windows Phone |
(3) 共有プロジェクトに配置する場合
PCLのリソースとして定義すると、画像の配置も一か所だけでよくなります。
ディレクトリなどの階層下にまとめるのも自由なので、Formsを使用するなら、この要領が一番お薦めです。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
Content = new Image {
Source = ImageSource.FromResource("App1.Images.classmethod.png")
};
}
}
なお、画像のビルドアクションは、「埋め込まれたリソース」に設定する必要があります。 ビルドアクションは、画像を右クリックして指定できます。
Android | iOS | Windows Phone |
3 イメージの配置 Aspect
Imageのエリアに画像をどのように展開するかを、プロパティAspectに設定します。
Aspect.AspectFill(デフォルト) | 画像の縦横比を保持したまま、Imageに収まるように縮小する |
Aspect.AspectFit | 画像の縦横比を保持したまま、Image全体に表示する(画像の一部が欠ける) |
Aspect.Fill | 画像の縦横比を無視して、Image全体に表示する(画像の縦横比が壊れる) |
サンプルは、3種類のAspect値によるImageの比較です。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
var width = Device.OnPlatform(360, 360, 480);
var height = Device.OnPlatform(120, 120, 180);
var layout = new AbsoluteLayout();
const int x = 10;
var y = 30;
foreach (Aspect aspect in Enum.GetValues(typeof(Aspect))) {
layout.Children.Add(new Label { Text = aspect.ToString() }, new Point(x, y));
y += 30;
layout.Children.Add(CreateImage(aspect), new Rectangle(x, y, width, height));
y += height + 30;
}
Content = layout;
}
static Image CreateImage(Aspect aspect) {
var image = new Image {
Source = ImageSource.FromResource("App1.Images.classmethod.png"),
BackgroundColor = Color .FromRgb(240,240,240),
Aspect = aspect
};
return image;
}
}
Android | iOS | Windows Phone |
透明度 Opacity
プロパティOpacity(0.0~1.0)で画像の透明度を指定します。 サンプルは、同じ画像を5段階の透明度で配置したものです。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
//アブソレートレイアウトの生成
var layout = new AbsoluteLayout();
//画像とラベルを5個配置
var y = 40;
var x = 20;//左余白
const int size = 120; // 画像のサイズ
for (var i = 0; i < 5; i++) {
var opacity = 0.25 * i; //透明度
//透明度を表示するためのラベルを生成
var label = new Label {
Text = String.Format("Opacity={0}", opacity)
};
//ラベルをレイアウトに配置
layout.Children.Add(label, new Point(x, y));
y += 10; // ラベルの分のオフセットを移動
//前景画像の作成
var imageFront = new Image {
Source = ImageSource.FromResource("App1.Images.classmethod.png"),
Aspect = Aspect.Fill,
Opacity = opacity,//透明度
};
//前景画像をレイアウトに配置
layout.Children.Add(imageFront, new Rectangle(x, y,size,size));
// 配置のオフセットを移動
y += size-50;
x += 50;
}
Content = layout; //アブソレートレイアウトをContentにセットする
}
}
Android | iOS | Windows Phone |
4 レイアウト OptionLayout
レイアウトは、イメージに固有のプロパティではありませんが、参考のため列挙させて頂きます。
(1) Center・End・Fill・Start
HorizontalOptions(横方向)及びVerticalOptions(縦方向)にLayoutOptionを指定することで、その配置を指定できます。
- Center 中央揃え
- End 最終(右)揃え
- Fill 全部使用
- Start 最初(左)揃え
次のサンプルは、HorizontalOptions(横方向)に各レイアウトを指定したものです。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
var ar = new[]{
LayoutOptions.Center,
LayoutOptions.End,
LayoutOptions.Fill,
LayoutOptions.Start};
var layout = new StackLayout();
foreach (var op in ar) {
layout.Children.Add(new Label {
Text = op.Alignment.ToString(), // LayoutOption名を表示する
});
var img = new Image {
Source = ImageSource.FromResource("App1.Images.classmethod.png"),
BackgroundColor = Color.FromRgb(240,240,240),
HorizontalOptions = op, // 4種類のLayoutOptionをそれぞれ設定する
WidthRequest = 100,
HeightRequest = 100
};
layout.Children.Add(img);
}
Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
Content = layout;
}
}
Android | iOS | Windows Phone |
(2) Fill・FillAndExpand
レイアウトオプションには、AndExpandが付いたものと、そうでないものがありますが、この違いは、余白を埋めるかどうかにあります。
次の例は、スタックレイアウトに同じイメージを3つ並べ、真ん中のイメージに、Fillを指定した場合とFillAndExpandを指定した場合の違いを示したものです。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
var layout = new StackLayout();
for (var i = 0; i < 3; i++) {
var img = new Image {
Source = ImageSource.FromResource("App1.Images.classmethod.png"),
BackgroundColor = Color.FromRgb(240, 240, 240)
};
if (i == 1) {
img.VerticalOptions = LayoutOptions.Fill; // Fillの場合
//img.VerticalOptions = LayoutOptions.FillAndExpand; // FillAndExpandの場合
}
layout.Children.Add(img);
}
Content = layout;
}
}
Fillの場合 | FillAndExpandの場合 |
5 まとめ
今回は、Xamarin.Fomrsにおけるイメージビューについて確認してみました。 イメージについては、枯れているというか、必要な機能は網羅されているので、これをレンダラー拡張して・・・というようなパターンは少ないかと思います。
また、「ImageSource.FromResource」でリソース指定することで、共通プロジェクトだけで画像リソースを管理できるので、できれはこの方法を積極的に使用するべきではと思います。
本記事は、2015年12月29日現在で最新の Xamarin.Forms 2.0.0.6490を使用して作成されています。
6 参考リンク
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
Xamarin記事一覧(SAPPOROWORKSの覚書)