Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigation Componentで先に知っておきたかったポイント

Navigation Componentで先に知っておきたかったポイント

* Navigation Component が、内部でどのような挙動をしているのか解説します
* 挙動を理解した後に Navigation Component でできることや、制約について話します

Takaki Hoshikawa

November 21, 2019
Tweet

More Decks by Takaki Hoshikawa

Other Decks in Programming

Transcript

  1. • 星川 貴樹 (@oboenikui) • エムスリー株式会社所属 (新卒3年目) • すき ◦

    Android ◦ プロ野球観戦 ◦ ネタTシャツ お ぼ え に く い
  2. • XMLで定義したグラフ(木構造) • <navigation> が内部ノード, <fragment> <activity> <dialog> が葉ノードになる ◦

    これらのノードをNavDestinationと呼ぶ • <action> <argument> <deepLink> は別扱い
  3. • NavController#navigate メソッドでdestinationとして指定 できるもの ◦ ただし <action> <deepLink> は別物 •

    <action> <deepLink> <argument> を持つことが可能 ◦ これらはNavDestinationのプロパティみたいなもの ◦ <action> に関しては <activity> では使えない
  4. <navigation android:id="@+id/navigation_a" app:startDestination="@+id/fragment_a1"> <fragment android:id="@+id/fragment_a1"/> <fragment android:id="@+id/fragment_a2"/> <navigation android:id="@+id/navigation_b" app:startDestination="@id/fragment_b1">

    <fragment android:id="@+id/fragment_b1"/> <fragment android:id="@+id/fragment_b2"/> </navigation> <navigation android:id="@+id/navigation_c" app:startDestination="@id/fragment_c"> <fragment android:id="@+id/fragment_c"/> <activity android:id="@+id/activity_c"/> </navigation> </navigation>
  5. 【本質的な話】 <fragment A1> は親ノードである <navigation A> の子ノードだったら 遷移可能。そのため <fragment A1>

    → <navigation B> の遷移が可能 親の子ノード 親の子ノード ではない者達 親
  6. 親の子ノード 親の子ノードではない者達 親の子ノード ではない者達 親 【本質的な話】 <fragment B2> は親の親ノードであ る

    <navigation A> の子ノードだっ たら遷移可能。そのため <fragment B2> → <navigation C> の遷移が可能
  7. 親の親の 子ノード 親 親の親 【本質的な話】 <fragment B2> は親の親ノードであ る <navigation

    A> の子ノードだっ たら遷移可能。そのため <fragment B2> → <navigation C> の遷移が可能 親や親の親の子ノードではない者達 親の子ノード
  8. • <navigation> 直下に <action> を設定すると、どの子孫ノードからも 実行できるActionが作られる <navigation ...> <fragment android:id="@+id/frag_a1">

    <!-- Fragment A1からのみ実行可能 --> <action app:destination="@id/actv_a"/> </fragment> <fragment android:id="@+id/frag_a2"/> <activity android:id="@+id/actv_a"/> </navigation> よく解説ブログに出てくる Action
  9. • <navigation> 直下に <action> を設定すると、どの子孫ノードからも 実行できるActionが作られる <navigation ...> <fragment android:id="@+id/frag_a1"/>

    <fragment android:id="@+id/frag_a2"/> <activity android:id="@+id/actv_a"/> <!-- どのFragmentからも実行可能 --> <action android:id="@+id/action_actv_a" app:destination="@id/actv_a" /> </navigation> Global Action
  10. Google I/Oでの発表によると、 • 各モジュールごとにNavigation XML を作る • メインモジュールのNavigation XML でincludeする

    のが想定解の模様 https://youtu.be/JFGq0asqSuA?t=1130 <!-- main_navigation.xml --> <navigation ...> <include app:graph="@navigation/login_navigation" /> <include app:graph="@navigation/home_navigation" /> ... </navigation>
  11. • BottomNavigationView などのナビゲーション用Viewで遷移する 場合、Fragmentが新たに生成される ◦ Google Newsアプリが近い挙動 • popBackStack しない限り生成済みのFragmentには戻らない、と

    いう挙動が徹底されている • ViewModelに表示に関する全てのデータを持たせ、Fragmentはそ れに従って表示するだけ、というのを徹底する思想?
  12. <!-- main_navigation.xml --> <navigation ...> <include app:graph="@navigation/sub_navigation"/> <action android:id="@+id/action_main_to_sub" app:destination="@+id/frag_sub"/>

    </navigation> <!-- sub_navigation.xml --> <navigation ...> <fragment android:id="@+id/frag_sub"> <argument android:name="arg" app:argType="string" .../> </fragment> </navigation>
  13. <!-- main_navigation.xml --> <navigation ...> <include app:graph="@navigation/sub_navigation"/> <action android:id="@+id/action_main_to_sub" app:destination="@+id/frag_sub">

    <argument android:name="arg" app:argType="string" .../> <!-- ここ --> </action> </navigation> <!-- sub_navigation.xml --> <navigation ...> <fragment android:id="@+id/frag_sub"> <argument android:name="arg" app:argType="string" .../> </fragment> </navigation>
  14. • Navigation Component の動作について解説をした • Navigation Component の中の事情を知った上で、 何ができるか/できないかについて解説した •

    Android Advent Calendar にも関連記事を書く予定 • 実験用に作ったサンプルリポジトリはこちら (最新版をpushし忘れたので後で確認してください^^;) https://github.com/oboenikui/navigation-experiment
  15. <navigation android:id="@+id/navigation_a" ...> <fragment .../> <fragment .../> <navigation android:id="@+id/navigation_b" app:startDestination="@+id/fragment_b1">

    <fragment android:id="@+id/fragment_b1" .../> <fragment android:id="@+id/fragment_b2" ...> </navigation> <navigation android:id="@+id/navigation_c" ...> </navigation>
  16. <navigation android:id="@+id/navigation_a" ...> <fragment .../> <fragment .../> <navigation android:id="@+id/navigation_b" ...>

    <navigation android:id="@+id/navigation_c" app:startDestination="@+id/fragment_c"> <fragment android:id="@+id/fragment_c" .../> <activity android:id="@+id/activity_c" ...> </navigation> </navigation>