だるろぐ

明日できることは、今日しない。

WinRT/XAML のお勉強 ―― さまざまな利用シーンに対応する

f:id:daruyanagi:20120917220924p:plain

今作ってる燃費管理アプリだけど、データの入出力と表示ぐらいまではあらかたできている。ただ、タッチ操作で日付や数値を入力するのは案外めんどい。 InputScope でソフトウェアキーボードの初期レイアウトを制御できるので多少マシにはなるけれど、やっぱりタッチ専用のユーザーインターフェイスがほしい。まぁ、でも、そこは妥協してもいい。問題は回転と解像度、スナップやでぇ……

回転と解像度

f:id:daruyanagi:20120920020106p:plain

たとえば、さっきのアプリを90度回転させてみる。これは惨めだ……。解像度を大きくすると画面が間延びしたりするのも悲しい。

XAML では、いわゆるテーブルレイアウトのようなことが可能な Grid が便利なのだけれど、あまり頼りすぎるとすぐに破たんする感じ。なるべく特定の解像度に依存しないフローレイアウトを行うようにしたいけれど……GridView を中心にしたほうがいいのかなぁ。

スナップ

f:id:daruyanagi:20120917220217p:plain

Windows ストアアプリは、端っこに寄せる「スナップ」をサポートしなければならない。

これを当初、HTML でいうレスポンシブレイアウト的な考えで対応しようと思っていたのだけれど、やってみるとあまり現実的ではない。というのも、さまざまな解像度に加え、回転まで考えると、考慮すべきケースが結構多くて手に負えなくなる。これを一つのビューで対応するのはできないこともないけど、結構大変だ。

そこで標準のテンプレートをよく読んでみたところ、どうも ViewState(どっかで聞いたような名前だけど気にしない) VisualState という仕組みがあるらしい。要は、縦表示なのか、スナップ状態なのか、といった表示の状態を管理してくれる。これを利用して、スナップ状態の時だけ表示されるリストを作ってしまえばいい。それあったまいいね! 標準テンプレートの最後のほうにある XAML をちょいちょいっといじるといいみたい。

<!-- The back button and title have different styles when snapped -->
<VisualState x:Name="Snapped">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
        </ObjectAnimationUsingKeyFrames>
                        
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentGrid" Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="logListView" Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

下の二つの ObjectAnimationUsingKeyFrames がそれで、contentGrid/logListView という二つのエレメントの Visibility を VisualState に応じて切り替えている。コードの意味はあんまりよくわかってなくて、辛うじて StoryBoard を知っている程度だけど、まぁ、コピペでいけるから今はそれでいいことにしておく。

f:id:daruyanagi:20120920022229p:plain

Windows ストアアプリは、こういうところが難しいなぁ、と思った。デスクトップアプリと違って、「未完成だけど公開してみます」というのはストアが認めてくれないわけで、ハードルはかなり高い。それに比べれば、開発者登録にお金が要るのはあまり大した問題じゃない気もする。けれど、一つアプリを完成させた(初めての Windows ストアアプリを提出してみました - だるろぐ)おかげで、ちょっとだけ慣れてきたかもしれない。やっぱり案ずるより産むが横山やすしやでぇ。

あとは WinRT <-> .NET Framework の関係があまりよくわかってなくて、MSDN ライブラリで迷子になったりするのもつらい。最初はファイルをどうやって開けばいいのかもわからなかった。けれど、これは経験を積んでいけば解消できそうな問題かな。