tmytのらくがき

個人の日記レベルです

効果的なトランジションでアプリをもっと素敵に

今年もこの季節になったようで、各地でいろんなアドベントカレンダーが開催されています。今年はWindows Phoneのアドベントカレンダーも開催されました。Twitterで主犯のid:iseebiから直々に


とお達しがあったので僕は3日目担当。

ぶっちゃけ最近あんまりなにもやってないので書くことも少なくて、Rxはのいえ大先生がおられるので自重するとして初心者向けとかそろそろ飽きてきたし…とか考えるとほとんど出来ること無くてやばい。ので、僕はSilverlight Toolkitを使ったお話をちょっぴり。

ページ遷移のときにトランジションアニメーションを付ける

トランジションの付け方は前にもここで紹介しましたがもう一度おさらい。

  1. Silverlight for Windows Phone Toolkit を参照に追加する
  2. RootFrameをPhoneApplicationFrameからTransitionFrameに変更
  3. 各ページにトランジション用のXAMLを書く

ざっと書くとこんな感じ。

参照に追加する

ソリューションエクスプローラから参照設定を右クリックして、参照の追加をクリック。その中からSilverlight Toolkitのアセンブリを選択。簡単ですね。

RootFrameを変更する

RootFrameを標準のPhoneApplicationFrameクラスからToolkitが提供するTransitionFrameに変更します。変更しないとトランジションが再生されません。変更はApp.xaml.csのInitializePhoneApplication関数を編集します。このメソッドに新たなコードを追加しないでくださいとかコメント書いてるのは無視します。

private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;

    // フレームを作成しますが、まだ RootVisual に設定しないでください。これによって、アプリケーションがレンダリングできる状態になるまで、
    // スプラッシュ スクリーンをアクティブなままにすることができます。
    RootFrame = new TransitionFrame(); // ここを変更
    RootFrame.Language = XmlLanguage.GetLanguage(AppResources.Language);
    RootFrame.Navigated += CompleteInitializePhoneApplication;

    // ナビゲーション エラーを処理します
    RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // 再初期化しないようにします
    phoneApplicationInitialized = true;
}
トランジション用のXAMLを書く

最後にXAMLを書いてできあがり。各ページにトランジションのXAMLを書きます。こんな感じ。

<toolkit:TransitionService.NavigationInTransition>
    <toolkit:NavigationInTransition>
        <toolkit:NavigationInTransition.Backward>
            <toolkit:TurnstileTransition Mode="BackwardIn"/>
        </toolkit:NavigationInTransition.Backward>
        <toolkit:NavigationInTransition.Forward>
            <toolkit:TurnstileTransition Mode="ForwardIn"/>
        </toolkit:NavigationInTransition.Forward>
    </toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>
<toolkit:TransitionService.NavigationOutTransition>
    <toolkit:NavigationOutTransition>
        <toolkit:NavigationOutTransition.Backward>
            <toolkit:TurnstileTransition Mode="BackwardOut"/>
        </toolkit:NavigationOutTransition.Backward>
        <toolkit:NavigationOutTransition.Forward>
            <toolkit:TurnstileTransition Mode="ForwardOut"/>
        </toolkit:NavigationOutTransition.Forward>
    </toolkit:NavigationOutTransition>
</toolkit:TransitionService.NavigationOutTransition>

ここからが本編

ここまではおさらいでした。僕も昔エントリしましたしid:ch3cooh393のサイトにあったりします。
さて、僕が紹介したいのはここからです。アプリの中でトランジションのアニメーションを変更したいときってあります。
たとえば、こんな感じの時。

メニューから設定画面を開いたときはWindows Phoneでよく見るぺろりんというアニメーション。そして、設定画面からさらに細かい設定を開くときはスライドするアニメーションを使いたい。そして拡張設定から戻るときはスライドアニメーションを再生し、設定からトップに戻るときはまたいつものぺろりんというアニメーションを再生して欲しい。
よくあるよね!といいたいところですがあんまり無いかもしれません。

コードで解決します

わりとうまい解決法を作ろうと思えば作れますが、今回はべたなやり方でいってみます。まずは、標準のアニメーションを先に挙げたXAMLを書いて実装します。
次に、ボタンを押してページ遷移する際にコードをちょっとだけ追加します。ビヘイビアでページを遷移させる場合には使えないのでトランジションを変更しつつページ遷移するビヘイビアを作りましょう。

private void OpenExtConfigButton_Click(object sender, RoutedEventArgs e)
{
    // ページの添付プロパティを変更してアニメーションを変更する
    TransitionService.SetNavigationInTransition(this, new NavigationInTransition()
    {
        Backward = new SlideTransition() { Mode = SlideTransitionMode.SlideRightFadeIn },
        Forward = new SlideTransition() { Mode = SlideTransitionMode.SlideLeftFadeIn }
    });
    TransitionService.SetNavigationOutTransition(this, new NavigationOutTransition()
    {
        Backward = new SlideTransition() { Mode = SlideTransitionMode.SlideRightFadeOut },
        Forward  = new SlideTransition() { Mode = SlideTransitionMode.SlideLeftFadeOut }
    });
    // ページ遷移を実行する
    NavigationService.Navigate(new Uri("/ExtConfig.xaml", UriKind.Relative));
}

まず遷移するコードをこういう感じに書き換えます。ページ遷移の前にごちゃごちゃいろいろ書いてあるところがトランジションアニメーションを変更するコードです。トランジションの設定は添付プロパティというので実装されているので、プロパティを変更するスタティックメソッドを呼び出して好きな感じに設定します。遷移先のアニメーションはこのコードで設定したアニメーションに対応するものを設定しておきましょう。
これでボタンを押して次のページへ遷移する際のアニメーションがスライドアニメーションになりました。でもこのままだと設定ページからトップに戻る際のアニメーションもスライドアニメーションで再生されてしまいます。どこかで標準のぺろりんというあれに戻してやらないといけません。そこで、いまトランジションを動的に書き換えたページへ遷移が完了した場合のメソッドつまり、ページに戻ってきたときに呼び出される関数を上書きして元に戻す処理を追加しましょう。

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    // 標準のOnNavigatedToを呼んであげる
    base.OnNavigatedTo(e);
    // トランジションを元に戻す
    TransitionService.SetNavigationInTransition(this, new NavigationInTransition()
    {
        Backward = new TurnstileTransition() { Mode = TurnstileTransitionMode.BackwardIn },
        Forward = new TurnstileTransition() { Mode = TurnstileTransitionMode.ForwardIn }
    });
    TransitionService.SetNavigationOutTransition(this, new NavigationOutTransition()
    {
        Backward = new TurnstileTransition() { Mode = TurnstileTransitionMode.BackwardOut },
        Forward = new TurnstileTransition() { Mode = TurnstileTransitionMode.ForwardOut }
    });
}

ページへ帰ってきたときにトランジションを元に戻します。この時のパラメタはXAMLに設定しているのと同じにしておくといいと思います。標準のOnNavigatedToはどこかで呼んであげましょう。呼んだ方がいいです。

これでメインページと設定の間はぺろりんというアニメーション、設定と詳細画面の間はスライドするアニメーションになっているはずです。結構書かないといけないことがおおくてあれげな感じですが、やってることはたいしたことないです。ライブラリでラップしまくればもっとお手軽に出来るようになるとおもいます。効果的なページ遷移をばしばし使っていくとみなさんのアプリケーションがもっと魅力的になると思います!