【Xamarin.Forms】ListViewのアイテムをタップしたら次の画面に遷移する


Xamarin初心者です。一般的なツール系アプリなんかでよく使うであろうListViewのアレコレを調べています。

これまでの記事で、Xamarin.FormsのListViewをXAMLで定義し、データソースの変更でUIが自動更新されるようになりました。

前々回:【Xamarin.Forms】ListView の CustomCell を XAML で定義する
前回:【Xamarin.Forms】ListViewのデータソースが変化したら自動でUIが更新されるようにする

今回はリストのアイテムをタップすると詳細画面に遷移するようなUIを作ってみようと思います。

本文

「リストのアイテムをタップすると詳細画面に遷移するようなUI」を分解すると、

  • アイテムのタップイベント通知を受け取る
  • 画面遷移する

の2つの要素に分かれます。それぞれ説明していきます。

アイテムのタップイベント通知を受け取る

まずは、ListViewのアイテムがタップされた時のイベントを受け取れるようにします。ListViewはアイテムがタップされるとItemSelectedイベントが発行されますので、以下のようにイベント発行時の処理を追加します。

MainPage.cs
scheduleList.ItemSelected += (sender, e) =>
{
    // ここに処理を追加
};

ListViewのタップイベントに限らず、Xamarin.Formsのイベント処理は基本的に上記のような感じで、Viewが持っている各イベントのプロパティにラムダで処理を追加するような書き方をするようです。(勉強中)

引数のsenderにはイベントを発行したオブジェクト(ここではscheduleList)が、eにはイベントデータ(ItemSelectedの場合はSelectedItemChangedEventArgs型のインスタンス)が渡されます。1

これでイベントを受け取って処理を実行できるようになりましたので、次は画面遷移です。

次の画面に遷移する

ここでは遷移先の画面を用意し、そこに遷移する部分を対応します。

ひとまず遷移先の画面はDetailPageという名前にし、Scheduleクラスの各プロパティを項目名つきで表示するだけの簡単なものにしておきます。

DetailPageのXAML、コードビハインドはこの記事の内容と直接関係しないため省略します。必要な場合はGitHubのリポジトリを参照してください。

次に、画面遷移をコーディングします。

Xamarin.Formsにおける画面遷移はApplicationクラスのMainPageプロパティに次のページのインスタンスをセットするだけ、というとてもシンプルなものです。先ほど// ここに処理を追加とコメントしていた部分に画面遷移の処理を入れます。

MainPage.xaml.cs
scheduleList.ItemSelected += (sender, e) =>
{
    Application.Current.MainPage = new DetailPage((Schedule) e.SelectedItem);
};

これを実行すると、以下のような動作になります。

これでListViewのアイテムをタップすると、タップしたアイテムの詳細画面に遷移できるようになりました。

しかし、これではまだ問題があります。実行して触ってみるとわかるのですが、前の一覧ページに戻れないのです。
ここで実装したように、ApplicationクラスのMainPageContentPageを継承したインスタンスをセットすると、このようにページをまるっと入れ替えてしまうような動きになります。

ページを入れ替えるのではなく、次のページへ移動していく(前にも戻れる)ようにするにはNavigationPageを利用します。
まず、App.xaml.csクラスの最初のMainPageプロパティへのセット部分を以下のように変更します。

App.xaml.cs
public App()
{
    InitializeComponent();
    MainPage = new NavigationPage(new MainPage());
}

これで、NavigationPageインスタンスにContentPage派生クラスのインスタンスをどんどん積み上げていく準備ができました。

次に、画面遷移する部分のコードを以下のように修正します。

MainPage.xaml.cs
scheduleList.ItemSelected += (sender, e) =>
{
    Navigation.PushAsync(new DetailPage((Schedule) e.SelectedItem));
}

実行すると、以下のようになります。

画面上部にナビゲーションバーが設置され、画面遷移した際にバックボタンが現れるようになりました。
これで、詳細画面に遷移してもバックボタンで戻ってこられるようになります。

なお、コミットは以下です。
https://github.com/chooyan-eng/XamarinPractice/commit/0e992274b0528278362aa65f0ad6c604f829c9e5

まとめ

以上で、「ListViewのアイテムをタップしたときに次の画面に遷移する」ができるようになりました。
このようなユーザーに選択させて次の画面に移る動作は、投稿データ、店舗データ、機能一覧など多くのアプリで使われるのではないかと思います。

Xamarin.Formsにおけるイベント処理のしかたはListViewだけでなくButtonなど他のViewでも同じように使えると思いますので、今回調査したのを基にいろいろ試してみようと思います。

また、画面遷移の方法として2パターン試してみましたが、元の画面戻れない1つ目の実装方法が決して悪いわけではなく、要件に合わせて使い分けられるようにしておくことが大事かと思います。

この記事のコード

コードはGitHubで公開しています。

chooyan-eng/XamarinPractice


  1. どのイベントにどの型のイベントデータが渡されるかは、処理を追加するプロパティの定義を見ると分かります。ItemSelectedの場合、ドキュメントを見るとpublic event EventHandler<Xamarin.Forms.SelectedItemChangedEventArgs> ItemSelected;と定義されているので、eSelectedItemChangedEventArgs型です。(まあドキュメントを見なくてもVisual Studioが型推論してくれはしますが)