【Fuse】カスタムコンポーネントを作って見た目を整える

今回は[こちら](https://www.fusetools.com/docs/tutorial/look-and-feel)のページに沿って進めていきます。

###イントロ

前の記事では、モックバックエンドを作成し、ビューをつなぎ合わせました。これでアプリの内側の主要な部分はほとんど完成しました。今回作るルック&フィールは、アプリの見た目だけでを指すのではなく、動作も想起させるものです。それは、アプリケーションのスタイルや色や、ユーザーインタラクションに対するアニメーションなどを含みます。

見た目の修正はFuseのライブリロード機能が非常に役に立ちます。なんども反復を行いながら、アプリの外観とコンポーネントを作っていきます。のこりのチュートリアルはこれを含めてあと3つです。がんばりましょう。（自分に向けて）

###背景色

まずはアプリの背景を変えることからスタートします。ハイキング編集ビューのデザインを見てみましょう。（この記事に掲載されているデザインは公式サイトのものを流用しています。）

![desing01.png](https://qiita-image-store.s3.amazonaws.com/0/100937/40ef00dc-c033-afd0-e7a7-338c235db455.png)

基本的に、暗い緑色の色合いが使われています。アプリの背景色を変更するには、`<App>`に`Background`プロパティを指定するだけです。

```MainView.ux
<App Background="#022328">
    <Router ux:Name="router" />
```

プレビューにはすぐ反映されますね。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/100937/54a491f7-73cc-839e-dfd1-538d46533abb.png)

では、UIコンポーネントを変更していきたいと思います。１画面ずつ進めていきたいと思います。

###ホーム画面の調整

ホーム画面の最終目標は下記のようになります。

![design02.png](https://qiita-image-store.s3.amazonaws.com/0/100937/3e2cf234-1efb-fd04-6cbc-768adac3db17.png)

主にセレクタを修正する必要がありそうです。現状、セレクターはボタンで作られていますが、デザインに合わせるため、カスタマイズしたいと思います。まずはボタンをカスタムコンポーネントに変更します。`<Button>`のかわりに、`<Panel>`と`<Text>`を組み合わせたものを使用します。

```HomePage.ux
<Each Items="{hikes}">
    <Panel>
        <Text Value="{name}" />
    </Panel>
</Each>
```

`<Button>`と同じようにクリックできるようにしたいので、`Clicked`属性を追加します。（`Clicked`は`<Button>`固有のものではなく、`<Panel>`をはじめ、多くのコンポーネントに備えられています。）

```HomePage.ux
<Each Items="{hikes}">
    <Panel Clicked="{goToHike}">
        <Text Value="{name}" />
    </Panel>
</Each>
```

プレビューを見てみると、クリックすれば、以前の`Button`の様に機能していることがわかります。要素のクリック可能範囲を変更する場合は`HitTestMode`を指定してください。

```HomePage.ux
<Each Items="{hikes}">
    <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
        <Text Value="{name}" />
    </Panel>
</Each>
```

`LocalBoundsAndChildren`を指定すると、`Panel`の範囲内と、`Panel`に含まれる子要素がクリックされたときに、「クリックされた」と判定します。

つづいて、テキストの色を変更します。背景色が結構暗いので、白を使いたいと思います。

```HomePage.ux
<Each Items="{hikes}">
    <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
        <Text Color="White" Value="{name}" />
    </Panel>
</Each>
```

直感的でわかりやすいですね。次はマージンを追加します。

```HomePage.ux
<Each Items="{hikes}">
    <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
        <Text Color="White" Value="{name}" Margin="20" />
    </Panel>
</Each>
```

これだけでもだいぶ見やすくなりました。しかし、ボタンの範囲がどこからどこまでかわかりにくいので、境界線を追加します。最初に全ての要素の上端に透明な高さ1の白い矩形を配置します。また最後の要素の下端にも１つだけ追加します。

```HomePage.ux
<Each Items="{hikes}">
	<Rectangle Height="1" Fill="#fff4" />
	
	<Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
	    <Text Color="White" Value="{name}" Margin="20" />
	</Panel>
</Each>
<Rectangle Height="1" Fill="#fff4" />
```

気づいたと思いますが、境界線はコンポーネント化できそうです。`Separator`コンポーネントを作り、使ってみましょう。

```HomePage.ux
<StackPanel>
    <Rectangle ux:Class="Separator" Height="1" Fill="#fff4" />

    <Each Items="{hikes}">
        <Separator />

        <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
            <Text Color="White" Value="{name}" Margin="20" />
        </Panel>
    </Each>

    <Separator />
</StackPanel>
```

再利用可能なコンポーネントを`ux:Class`で作るとき、整理しておくために、独自のファイルの中に入れておくことがよくあります。ファイル内のインスタンス化したい箇所に小さなコンポーネントを作ることはよいと思います。しかし、ファイルの外におくと、そのコンポーネントが、どのように使われるのかがわかりづらくなります。`Separator`のような小さいものは、必要な場所に宣言しておく方がよいでしょう。

デザインに近づいてきたので、アニメーションを追加したいと思います。

クリックした瞬間に、短い時間をかけてサイズ小さくなるアニメーションをつくります。Fuseはアニメーションやインタラクションを表現するのに、強力で簡単な機能を提供しています。主な役割は「トリガー」と「アニメーター」の二つがあります。トリガーはイベントやジェスチャーを検出するときや、Fuseの他の状態変更やユーザーインプットに使われます。トリガーはアニメーターを使ってこれらの入力に応答し、状態の変更、アニメーションの実行を行います。トリガーとアニメーターは、自由度が高く、使いやすいように設計されています。

上で説明したアニメーションをUXマークアップで表現してみましょう。まずは「クリックしている間」という状態を追加します。これには`WhilePressed`と呼ばれるトリガーが用意されています。

```HomePage.ux
<Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
    <Text Color="White" Value="{name}" Margin="20" />
    <WhilePressed>
    
    </WhilePressed>
</Panel>
```

続いて、「サイズを変える」部分です。`WhilePressed`の中に`Scale`というアニメータを追加します。

```HomePage.ux
<Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
    <Text Color="White" Value="{name}" Margin="20" />
    <WhilePressed>
    	<Scale Factor=".95 />
    </WhilePressed>
</Panel>
```

英語を書いているように直感的に実装できます。どのくらいのサイズになるかは`Factor`に指定します。`Scale`の場合、1を基準として指定します。2なら2倍、.5なら半分のサイズになります。ここでは若干小さくしたいので.95を指定します。

プレビューを見てみると、実際にプレスしている間だけ少し小さくなるのがわかります。今度はアニメーションさせるために、`Duration`を追加します。通常のサイズから、`Factor`で指定したサイズになるまでにかける時間を秒単位で示します。

```HomePage.ux
<Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
    <Text Color="White" Value="{name}" Margin="20" />
    <WhilePressed>
    	<Scale Factor=".95 Duration=".08" />
    </WhilePressed>
</Panel>
```

これで押した瞬間にスムーズに小さくなるようになりました。しかし、アニメーションはデフォルトで線形になってしまいます。アニメーションするスピードは最初から最後まで変わりません。もうすこし気持ちよくするために、イージングをつけましょう。多くのツールで実装されている[イージング](http://easings.net/ja)をFuseも用意しています。（ただし、名前が違う可能性があります。）

リニアにちょっと近いですが、アニメーションの終盤がすこし滑らかになる、`QuadraticOut`を指定してみましょう。

```HomePage.ux
<Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
    <Text Color="White" Value="{name}" Margin="20" />
    <WhilePressed>
    	<Scale Factor=".95 Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>
```

0.08秒だとわかりにくいので、 `Duration`に.5くらいを指定するとイージングしているのがよくわかると思います。

トリガーとアニメーターについての詳細に関しては、[ビデオ](https://www.youtube.com/watch?v=bT1npBvXEzw)で確認することができます。

さて、このページを完成させる前に、ページにタイトルを追加しましょう。画面上部に若干の余白と、テキストをドッキングしたいと思います。今ある部分を`DockPanel`に移動します。

```HomePage.ux
<DockPanel>
    <ScrollView>
        <StackPanel>
            <Rectangle ux:Class="Separator" Height="1" Fill="#fff4" />

            <Each Items="{hikes}">
                <Separator />

                <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
                    <Text Color="White" Value="{name}" Margin="20" />

                    <WhilePressed>
                        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
                    </WhilePressed>
                </Panel>
            </Each>

            <Separator />
        </StackPanel>
    </ScrollView>
</DockPanel>
```

`ScrollView`と同じ階層に`Text`要素を追加します。
 
```HomePage.ux
<DockPanel>
	<Text Color="White" FontSize="30" TextAlignment="Center" Dock="Top" Margin="0,50">Recent Hikes</Text>
    <ScrollView>
```

これでタイトルが表示されます。HomePage.ux全体を見てみると、`Text`要素はいずれも色が同じです。背景色が暗いので、おそらくこの1ページだけでなく、他のところでも使われることが想定されます。そのため、コンポーネント化したいと思います。

他のページからも参照できるように、他のファイルに切り出します。まずは`components`というフォルダを作ります。

```全体の構造
.
|- MainView.ux
|- Components
|- Modules
|- Pages
```

このディレクトリは様々なコンポーネントを入れておく場所にしましょう。では白いテキスト用のコンポーネントファイル`hikr.Text.ux`ファイルを作成します。

```hikr.Text.ux
<Text ux:Class="hikr.Text" Color="White" />
```

`HomePage.ux`に戻って、`hikr.Text`をつかってみましょう。

```HomePage.ux
<DockPanel>
    <hikr.Text FontSize="30" TextAlignment="Center" Dock="Top" Margin="0,50">Recent Hikes</hikr.Text>
    <ScrollView>
        <StackPanel>
            <Rectangle ux:Class="Separator" Height="1" Fill="#fff4" />

            <Each Items="{hikes}">
                <Separator />

                <Panel HitTestMode="LocalBoundsAndChildren" Clicked="{goToHike}">
                    <hikr.Text Value="{name}" Margin="20" />

                    <WhilePressed>
                        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
                    </WhilePressed>
                </Panel>
            </Each>

            <Separator />
        </StackPanel>
    </ScrollView>
</DockPanel>
```

このページは背景以外完成です！！完成図はこんな感じですね。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/100937/ea6f4975-ea7c-dfc9-d12b-9b753f2394b8.png)

このチュートリアルでは、まず、Fuseのビルトインコンポーネントにスタイリングして、コンポーネント化できそうなら抽出して外部に切り出す方法を採用しています。これにより一貫性を保つことができ、より高速に実装することができます。

###編集ビューを調整しよう

編集ビューで目指すべきビジュアルデザインは下記です。

![desing01.png](https://qiita-image-store.s3.amazonaws.com/0/100937/40ef00dc-c033-afd0-e7a7-338c235db455.png)

このページで修正するのはキャンセル/保存ボタンと、インプットフィールドの部分です。まずはボタンから始めます。

####ボタンの調整

ボタンはまだ何もスタイリングされていません。これを独自のカスタム表示にしたいので、独自のコンポーネントを作成します。まずは`Save`ボタンを`Text`を含む`Panel`にします。先ほど作ったばかりの`hikr.Text`を使いましょう。

```EditHikePage.ux
<Panel Clicked="{save}">
    <hikr.Text Value="Save" />
</Panel>
<Button Text="Cancel" Clicked="{cancel}" />
```

テキストの位置を中央にしたいので、インスタンスにプロパティを追加します。

```EditHikePage.ux
<Panel Clicked="{save}">
    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />
</Panel>
```

次に背景を変更します。まず、`Rectangle`を追加し、デザインと同じ背景色にします。ついでに角丸もつけます。

```EditHikePage.ux
<Panel Clicked="{save}">
    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4" />

    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />
</Panel>
```

最後にボタンの下部にある、影を追加し、余白を整えます。影はCSS同様、`Angle`,`Distance`,`Spread`,`Size`,`Color`を指定します。

```EditHikePage.ux
<Panel Clicked="{save}" Margin="10" Padding="10">
    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />
</Panel>
```

見た目はこのように変わりました。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/100937/0b09c8df-c509-b027-24a6-b41fcce622e5.png)

続いてアニメーションをつけていきます。先ほどつけたように`whilePressed`を追加します。

```EditHikePage.ux
<Panel Clicked="{save}" Margin="10" Padding="10">
    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />

    <WhilePressed>
        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>
```

これでボタンは出来上がったので、コンポーネント化します。`Panel`からインスタンスへ`Clicked`を移動するのを忘れずに。

```EditHikePage.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10">
    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />

    <WhilePressed>
        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>

<hikr.Button Clicked="{save}" />
<Button Text="Cancel" Clicked="{cancel}" />
```

次は、このコンポーネントをキャンセルでも使えるようにハードコーディングされた「Save」という文言を変更できるようにしなければなりません。コンポーネントにプロパティを追加する必要があります。これを可能にするのが`ux:Property`です。コンポーネントの部分を少し変更します。

```EditHikePage.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10">
    <string ux:Property="Text" />

    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="Save" FontSize="16" TextAlignment="Center" />

    <WhilePressed>
        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>
```

プロパティを定義することができました。ただしまだ中に`Save`が残されています。定義したプロパティの値を表示するように修正する必要があります。今まで使ってきたデータバインディングと同じように書くことができます。

```EditHikePage.ux
<hikr.Text Value="{ReadProperty Text}" FontSize="16" TextAlignment="Center" />
```

`ReadProperty`が追加されています。これはFuseにバインディングタイプを伝える役割を持っています。これでインスタンス側でプロパティを設定することができるようになりました。キャンセルボタンにも適用する前に、違うファイルに切り出しておきましょう。

```hikr.Button.ux
<Panel ux:Class="hikr.Button" Margin="10" Padding="10">
    <string ux:Property="Text" />

    <Rectangle Layer="Background" Color="#125F63" CornerRadius="4">
        <DropShadow Angle="90" Distance="1" Spread="0.2" Size="2" Color="#00000060" />
    </Rectangle>

    <hikr.Text Value="{ReadProperty Text}" FontSize="16" TextAlignment="Center" />

    <WhilePressed>
        <Scale Factor=".95" Duration=".08" Easing="QuadraticOut" />
    </WhilePressed>
</Panel>
```

コンポーネントを使ってインスタンス化します。

```EditHikePage.ux
<hikr.Button Text="Save" Clicked="{save}" />
<hikr.Button Text="Cancel" Clicked="{cancel}" />
```

コンポーネント化についてもっと情報が欲しい場合は、[Creating Components](https://www.fusetools.com/docs/basics/creating-components)の項目をご覧ください。

ボタンの見た目はできたので、つぎはこの二つを横に並べます。

ならべて配置するときは`Grid`を使用します。`Grid`は`Panel`の一つで、指定された行と、列に基づいて、領域を分割し、子要素をそれに沿って配置していきます。デフォルトではその領域は均等になるように設定されています。

```EditHikePage.ux
<Grid ColumnCount="2">
    <hikr.Button Text="Cancel" Clicked="{cancel}" />
    <hikr.Button Text="Save" Clicked="{save}" />
</Grid>
```

`ColumnCount`に2を指定しました。こうすると、2つの列が出来上がります。また、デザインに合わせて、ボタンの順序を変更しました。

最後に、このグリッドを画面の最下部に配置しましょう。ページ全体を`DockPanel`の中に移動し、`Dock=Bottom`を指定します。ボタンのカスタマイズは以上で終了です。

```EditHikePage.ux
<Page ux:Class="EditHikePage">
    <Router ux:Dependency="router" />

    <JavaScript File="EditHikePage.js" />

    <DockPanel>
        <Grid ColumnCount="2" Dock="Bottom">
            <hikr.Button Text="Cancel" Clicked="{cancel}" />
            <hikr.Button Text="Save" Clicked="{save}" />
        </Grid>

        <ScrollView>
            <StackPanel>
                <Text Value="{name}" />

                <Text>Name:</Text>
                <TextBox Value="{name}" />

                <Text>Location:</Text>
                <TextBox Value="{location}" />

                <Text>Distance (km):</Text>
                <TextBox Value="{distance}" InputHint="Decimal" />

                <Text>Rating:</Text>
                <TextBox Value="{rating}" InputHint="Integer" />

                <Text>Comments:</Text>
                <TextView Value="{comments}" TextWrapping="Wrap" />
            </StackPanel>
        </ScrollView>
    </DockPanel>
</Page>
```

####入力部分を調整しよう

ボタンの調整が終わったので、入力フィールドをデザインに合わせていきます。

まずは、最初に不要なテキストが入っているので、削除します。そして、テキストを自作の`hikr.Text`コンポーネントに置き換えましょう。透明度やマージンも調整します。まずは`name`だけカスタマイズします。

```EditHikePage.ux
<hikr.Text Opacity=".6" Margin="0,0,0,5">Name:</hikr.Text>
<TextBox Value="{name}" />
```

コンポーネント化します。

```EditHikePage.ux
<hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5">Name:</hikr.Text>

<TitleText>Name:</TitleText>
<TextBox Value="{name}" />
```

見た通り、自作のコンポーネントを継承しています。他の部分にも適用します。

```EditHikePage.ux
<hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5" />

<TitleText>Name:</TitleText>
<TextBox Value="{name}" />

<TitleText>Location:</TitleText>
<TextBox Value="{location}" />

<TitleText>Distance (km):</TitleText>
<TextBox Value="{distance}" InputHint="Decimal" />

<TitleText>Rating:</TitleText>
<TextBox Value="{rating}" InputHint="Integer" />

<TitleText>Comments:</TitleText>
<TextView Value="{comments}" TextWrapping="Wrap" />
```

さらに、フィールドごとの余白も調整していきます。まずは親の`StackPanel`に`Passing`を追加します。

```EditHikePage.ux
<StackPanel Padding="10">
    <hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5" />
```

`<StackPanel>`には`ItemSpacing`を追加することができます。子要素間のスペースを一度に指定できます。

```EditHikePage.ux
<StackPanel Padding="10" ItemSpacing="10">
    <hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5" />
```

`ItemSpacing`はすべての子要素に余白を設定してしまうので、タイトルと入力フィールドの間にも無駄な余白が空いてしまいました。これを防ぐために、グループ化します。

```EditHikePage.ux
<StackPanel ItemSpacing="10" Padding="10">
    <hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5" />

    <StackPanel>
        <TitleText>Name:</TitleText>
        <TextBox Value="{name}" />
    </StackPanel>

    <StackPanel>
        <TitleText>Location:</TitleText>
        <TextBox Value="{location}" />
    </StackPanel>

    <StackPanel>
        <TitleText>Distance (km):</TitleText>
        <TextBox Value="{distance}" InputHint="Decimal" />
    </StackPanel>

    <StackPanel>
        <TitleText>Rating:</TitleText>
        <TextBox Value="{rating}" InputHint="Integer" />
    </StackPanel>

    <StackPanel>
        <TitleText>Comments:</TitleText>
        <TextView Value="{comments}" TextWrapping="Wrap" />
    </StackPanel>
</StackPanel>
```

次は各アイテムを調整していきます。まずは`TextBox`を調整します。キャレットの色をかえ、アイテム自身のパディングも指定します。

```EditHikePage.ux
<StackPanel>
    <TitleText>Name:</TitleText>
    <TextBox TextColor="White" CaretColor="White" Padding="10,10,0,10" Value="{name}" />
</StackPanel>
```

これをコンポーネントとして、別ファイルに切り出し、インスタンス化します。

```hikr.TextBox.ux
<TextBox ux:Class="hikr.TextBox" TextColor="White" CaretColor="White" Padding="10,10,0,10" />
```

```EditHikePage.ux
<StackPanel ItemSpacing="10" Padding="10">
    <hikr.Text ux:Class="TitleText" Opacity=".6" Margin="0,0,0,5" />

    <StackPanel>
        <TitleText>Name:</TitleText>
        <hikr.TextBox Value="{name}" />
    </StackPanel>

    <StackPanel>
        <TitleText>Location:</TitleText>
        <hikr.TextBox Value="{location}" />
    </StackPanel>

    <StackPanel>
        <TitleText>Distance (km):</TitleText>
        <hikr.TextBox Value="{distance}" InputHint="Decimal" />
    </StackPanel>

    <StackPanel>
        <TitleText>Rating:</TitleText>
        <hikr.TextBox Value="{rating}" InputHint="Integer" />
    </StackPanel>
```

最後の項目の`TextView`を編集しましょう。これは複数行用のTextViewなので、違う作り方になりそうですが、基本的には、先ほどと同じ`TextColor`,`CaretColor`,`Padding`を指定します。

```EditHikePage.ux
<StackPanel>
    <TitleText>Comments:</TitleText>
    <TextView TextColor="White" CaretColor="White" Padding="5" Value="{comments}" TextWrapping="Wrap" />
</StackPanel>
```

背景に、透明度を持った丸みのある矩形を追加します。

```EditHikePage.ux
<StackPanel>
    <TitleText>Comments:</TitleText>
    <TextView TextColor="White" CaretColor="White" Padding="5" Value="{comments}" TextWrapping="Wrap">
        <Rectangle Layer="Background" Color="#fff2" CornerRadius="4" />
    </TextView>
</StackPanel>
```

これでOKでしょう。`TextView`はこの箇所にしか使われていないので、コンポーネント化は必要ないところです。しかし、他と揃えるために、外部ファイル化しておきましょう。

```hikr.TextView.ux
<TextView ux:Class="hikr.TextView" TextColor="White" CaretColor="White" Padding="5">
    <Rectangle Layer="Background" Color="#fff2" CornerRadius="4" />
</TextView>
```

```EditHikePage.ux
<StackPanel>
    <TitleText>Comments:</TitleText>
    <hikr.TextView Value="{comments}" TextWrapping="Wrap" />
</StackPanel>
```

これで編集ビューの調整も終わりです。下記のようになりました！

![04.png](https://qiita-image-store.s3.amazonaws.com/0/100937/68e568ab-7473-acb9-c833-34b2cf603b69.png)

###アプリに背景画像を設定する

今まで背景は単一色でしたが、アプリ全体に背景画像を適用します。画像用のディレクトリ`Assets`を作りましょう。

```ツリー構造
.
|- MainView.ux
|- Assets
|- Components
|- Modules
|- Pages
```

背景に使う画像は下記です。`Assets`ディレクトリに保存します。

![background.png](https://qiita-image-store.s3.amazonaws.com/0/100937/7c2a6e70-4f31-1ff7-ca24-b6aa8e6a43bf.png)

この背景画像をアプリ全体に同時に適用したいと思うでしょうが、ページそれぞれに適用することで、ページ遷移の際に背景も一緒に移動してくれるようになります。まずはホーム画面に適用して、出来上がったら他のページにコピーしましょう。

`Page`クラスに`image`要素を追加して、画像を適用しましょう。`File`プロパティの値と、`HomePage.ux`との位置関係、画像の拡張子に注意してください。

```HomePage.ux
<Image Layer="Background" File="../Assets/background.png" StretchMode="Fill" Opacity=".7" />
```

このままだと大きい端末で見たときなどに、ページ全体に背景画像がひろがりません。`Image`はデフォルトで画像のアスペクト比を変更せず利用可能な領域に収まるように拡大縮小するからです。全面をカバーできるようにプロパティを調整します。ついでに透過させて、背景色となじませましょう。

```HomePage.ux
<Page ux:Class="HomePage">
    <Image Layer="Background" File="../Assets/background.jpg"  StretchMode="Fill" />

    <Router ux:Dependency="router" />
```

`Image`の詳細を説明した[ビデオ](https://www.youtube.com/watch?v=d5lA0yyq9g0)もあるので、そちらもご覧ください。

背景の設定ができたので、コンポーネント化して、編集ビューにも適用しましょう。今回は画像だけでなくページ全体をひとつのコンポーネントとします。

```hikr.page.ux
<Page ux:Class="hikr.Page">
    <Image Layer="Background" File="../Assets/background.png" StretchMode="Fill" Opacity=".7" />
</Page>
```

最後に、ホーム画面と編集ビューに適用します。


```HomePage.ux
<hikr.Page ux:Class="HomePage">
    <Router ux:Dependency="router" />

    ...
</hikr.Page>
```
```EditHikePage.ux
<hikr.Page ux:Class="EditHikePage">
    <Router ux:Dependency="router" />

    ...
</hikr.Page>
```

アプリ本体の見た目が完成しました。

###ステータスバーを調整しよう

あと一息です。がんばれ、おれ。最後はステータスバーです。アプリ本体の見栄えは良くなりましたが、ステータスバーがマッチしていません。またiOSとAndroidでそれぞれのステータスバーが表示されることも問題です。これを調整していきます。

これを調整するために、Fuseは`iOS.StatusBarConfig`クラスと、`Android.StatusBarConfig`クラスを用意しています。まずはiOSから使い方をみていきましょう。

```MainView.ux
<App Background="#022328">
    <iOS.StatusBarConfig Style="Light" />

    <Router ux:Name="router" />
```

続いてAndoridの対応です。

```MainView.ux
<App Background="#022328">
    <iOS.StatusBarConfig Style="Light" />
    <Android.StatusBarConfig Color="#022328" />
```

これで、各端末でアプリにマッチしたステータスバーが表示されるはずです。ここで追加した`iOS.StatusBarConfig`と`Android.StatusBarConfig`はアプリ内で必ず1つだけ記述してください。ステータスバーについての詳細は、[ビデオ](https://www.youtube.com/watch?v=EBopndSkk5c)が用意されています。

###今回の成果

ボタンや入力フィールドの見た目を調整し、綺麗なアプリに大変身しました！！

![タイトルなし.gif](https://qiita-image-store.s3.amazonaws.com/0/100937/df5ccfd9-043c-6657-dd26-096086aa667e.gif)
今回もこのgifは公式サイトのビデオをgif化したものです。

今回はたくさんの改修があり、別ファイルとしてコンポーネント化したものがたくさんあったので、Githubのリンクをまとめています。

- [Assets/Background.jpg](https://github.com/fusetools/hikr/blob/chapter-6/Assets/background.jpg)
- [Components/hikr.Button.ux](https://github.com/fusetools/hikr/blob/chapter-6/Components/hikr.Button.ux)
- [Components/hikr.Page.ux](https://github.com/fusetools/hikr/blob/chapter-6/Components/hikr.Page.ux)
- [Components/hikr.Text.ux](https://github.com/fusetools/hikr/blob/chapter-6/Components/hikr.Text.ux)
- [Components/hikr.TextBox.ux](https://github.com/fusetools/hikr/blob/chapter-6/Components/hikr.TextBox.ux)
- [Components/hikr.TextView.ux](https://github.com/fusetools/hikr/blob/chapter-6/Components/hikr.TextView.ux)
- [Pages/EditHikePage.ux](https://github.com/fusetools/hikr/blob/chapter-6/Pages/EditHikePage.ux)
- [Pages/HomePage.ux](https://github.com/fusetools/hikr/blob/chapter-6/Pages/HomePage.ux)
- [MainView.ux](https://github.com/fusetools/hikr/blob/chapter-6/MainView.ux)

###今回登場したFuseのコンポーネントやプロパティたち
- [Background](https://www.fusetools.com/docs/fuse/appbase/background)
- [Panel](https://www.fusetools.com/docs/fuse/controls/panel)
- [HitTestMode](https://www.fusetools.com/docs/fuse/elements/element/hittestmode)
- [Margin](https://www.fusetools.com/docs/fuse/elements/element/margin)
- [Rectangle](https://www.fusetools.com/docs/fuse/controls/rectangle)
- [StackPanel](https://www.fusetools.com/docs/fuse/controls/stackpanel)
- [WhilePressed](https://www.fusetools.com/docs/fuse/gestures/whilepressed)
- [Scale](https://www.fusetools.com/docs/fuse/animations/scale)
- [DockPanel](https://www.fusetools.com/docs/fuse/controls/dockpanel)
- [DropShadow](https://www.fusetools.com/docs/fuse/effects/dropshadow)
- [Grid](https://www.fusetools.com/docs/fuse/controls/grid)
- [ItemSpacing](https://www.fusetools.com/docs/fuse/controls/stackpanel/itemspacing)
- [Image](https://www.fusetools.com/docs/fuse/controls/image)
- [iOS.StatusBarConfig](https://www.fusetools.com/docs/fuse/ios/statusbarconfig)
- [Android.StatusBarConfig](https://www.fusetools.com/docs/fuse/android/statusbarconfig)

###明日は

最後はスプラッシュスクリーンを作って、アプリを完成させます。だいたいのアーキテクチャはできあがっているので、問題なくできると思います！お楽しみに！