読者です 読者をやめる 読者になる 読者になる

眠いしお腹すいたし(´・ω・`)

C#関連を主に書きます。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Prism.FormsでランダムにNavigationが変わるアプリを作ってみた(^^)/

こちらの記事は

qiita.com

8日目の記事になります。

初心者枠ということでお手柔らかにお願い致します。

Xamarin.Formsのナビゲーション

developer.xamarin.com

Xanarin,FormsのNavigationには大きく分けて4種類あります。

  1. NavigationPage
  2. MasterDetailPage
  3. TabbedPage
  4. CarouselPage

NavigationPageは非常にシンプルで1本道なナビゲーションです。

それに対してTabbedPage / CarouselPageはPageを横に並べます。

MasterDetailPageはMasterPageでページを選んでDetailにPageを表示するようなNavigationが可能です、

一般的に標準的なアプリにおいてiOSはTabナビゲーション、AndroidはMasterDetailが採用されていることが多いです。

これは各プラットフォームの推奨デザインによります。

同じアプリでもプラットフォーム毎にナビゲーションを最適化しておく事は大切です。

Xamarin.Formsはクロスプラットフォームで同じアプリを作る仕組み・・・・

ナビゲーションを簡単に変更するなんて出来ないんじゃないの・・・・?

そんなお考えのそこのあなた(; ・`д・´)m9

今回ご紹介する方法ならできるんです\(^o^)/

それでは方法をご紹介してみましょう。

Prism.Formsの利用

今回のサンプルではPrism.Formsを使用します。

Prism.FormsはMVVMライブラリでかなり巨大なライブラリになります。

Prismに関して、なにそれ美味しいの?という方は

www.nuits.jp

こちらをご覧ください、

はじめに

考え方

TabbedPageを右に90度回転させるとMasterDetailっぽくありません?

そういう事です。

二つのアプローチ

  1. TabbedPageを継承してCustomRendererでMasterDetailのような見た目のNavigationを作成する。

  2. MasterDetailPageを継承してTabbedPageに近いインターフェースと仕組みを持ったクラスを作成する。

1番が理想形です。が・・・すいません。完成しませんでした・・・

今回は2番のアプローチで作成を行います。

プログラム

今回のサンプルプログラムはこちらになります。

github.com

MasterDetail拡張

Prism.Forms_NavigationSample/TabbedMasterDetailPage.cs at master · yuka1984/Prism.Forms_NavigationSample · GitHub

gist.github.com

MasterDetailクラスを継承し更に IViewContainer、IPageContainer、IItemsViewを追加します。

この3つはabstractクラスであるMultiPageのインターフェースです。MultiPageはTabbedPageのベースクラスです。

実際には今回の範囲ではこのインターフェースを持つ必要はないのですが形だけでも似せるために実装しています。

MasterPageにはListViewをおいてChildrenと結び付けを行っています。

Childrenが選択された場合にはDetailに該当ページをNavigationPageに包んでセットします。

そのほかChangePageなどを実装しています。

PageNavigationServiceの拡張

Prism.Forms_NavigationSample/CustomPageNavigationService.cs at master · yuka1984/Prism.Forms_NavigationSample · GitHub

本来であればPrism.FormsのPageNavigationServiceを継承してカスタム、という形にしたかったのですが期待する動作をさせるためにはどうしても無理であったためPrism.Formsのコードを持ってきてカスタマイズを行いました。

変更点は先ほど作成したTabbedMasterDetailPage用の処理関数ProcessNavigationForTabbedPageを追加し呼び出されるようにしたことです。

この関数の中身自体はTabbedPage用の関数とほぼ同じです。

先ほど説明した2つのアプローチの1番であればNavigationServiceをカスタマイズする必要はなく、そういういみでもアプローチ1は理想形と言えます。

Appクラス

Prism.Forms_NavigationSample/App.cs at master · yuka1984/Prism.Forms_NavigationSample · GitHub

gist.github.com

Appクラスはこのように実装しています。

あまり良い実装ではないです。

RegisterTypesにてランダムにNavigationPageを登録しています。

この時に名前をRootPageという名前で登録することでawait NavigationService.NavigateAsync("RootPage/Content2");というように指定することができます。

ここまでの実装によりMasterDetailな見た目だけどロジック的にはTabbedPageと共通で実装することができました。

終わりに

Xamarin.FormsはMVVMパターン・・・みたいに言われることがあるのですがなんか違う気がしてきています。

というよりMVVMってなんだろう。MVVMとはいったいなんだろう・・・・なんなんだぁ(/・ω・)/

MVVMを考えるときにNavigationを入れちゃだめだ(;^ω^)

clean architecture Reactive・・・・

:(´◦ω◦`):