プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

Xamarin.Formsでページの壁紙をイイ感じに表示したい

今日(2018/12/12)時点の最新のXamarin.Forms(not Preview)でのお話

例によって正しいかどうかはご自身で判断してください

  • 対象はiOS(Androidは確認してないから知らない)
  • Emulatorでのみ動作確認
  • Visual Studio 2017でXamarin.Formsのプロジェクト作ってそのテンプレートをいじって試してみる
  • いいかんじ = アスペクト比固定でFill

です

ContentPage.BackgroundImageに指定

375 x 812ピクセルの壁紙をiPhone XSエミュレーター使って確認します

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage"
    BackgroundImage="bg375.jpg">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    </StackLayout>

</ContentPage>

結果

f:id:puni-o:20181212133641j:plain

なんかよさそうですね

壁紙のサイズを100 x 178ピクセルにして試す

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage"
    BackgroundImage="bg100.jpg">

以下略
</ContentPage>

結果

f:id:puni-o:20181212133656j:plain

はい

ということでContentPage.BackgroundImageはあきらめました (BackgroundImageを制御するものが見つからなかったので)

壁紙のサイズを端末のサイズに合わせればいいじゃんと思うかもしれませんが、Androidに限らずiPhoneも今やいろんなアスペクト比の端末があるんでダメですね

Imageを使う

ググると大体この方法ですね

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage">

    <Grid>
        <Image Aspect="AspectFill" Source="bg100.jpg"/>
        <StackLayout>
            <!-- Place new controls here -->
            <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
        </StackLayout>
    </Grid>
</ContentPage>

結果

f:id:puni-o:20181212134847j:plain

今度こそよさそう?

UseSafeAreaを指定する

iPhone Xが出てできた概念ですかね?どういうものかはUseSafeAreaでググればすぐに画像とかでてくると思います。このプロパティを有効にしておけばノッチとかその辺を除いたサイズでどうにかしてくれるってやつですね

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
    ios:Page.UseSafeArea="True"
    >

    <Grid>
        <Image Aspect="AspectFill" Source="bg375.jpg"/>
以下略

結果

f:id:puni-o:20181212140559j:plain

UseSafeAreaの効果がよくわかりますね (

ダメだけどContentPage.BackgroundImageで試してみる

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
    ios:Page.UseSafeArea="True"
    BackgroundImage="bg375.jpg"
    >
以下略

結果

f:id:puni-o:20181212140846j:plain

こっちでイキたいけどいイケないもどかしさ

ImageをContentの外側まで引き延ばす

これが現在の私の答えです

MainPage.xaml

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:BackgroundImageTest"
    x:Class="BackgroundImageTest.MainPage"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
    ios:Page.UseSafeArea="True"
    >

    <Grid>
        <Image x:Name="BgImage" Aspect="AspectFill" Source="bg375.jpg"/>
以下略

MainPage.xaml.cs

protected override void OnAppearing()
{
    base.OnAppearing();
    var inset = On<iOS>().SafeAreaInsets();
    BgImage.Margin = new Thickness(-inset.Left, -inset.Top, -inset.Right, -inset.Bottom);
}

結果

f:id:puni-o:20181212141349j:plain

他の端末でもいい感じに壁紙してくれるんじゃないでしょうか(多分)