113 Views
August 20, 19
スライド概要
2019年8月19日に開催されたヤフーBonfire Android #5の内容です。
https://yj-meetup.connpass.com/event/136481/
2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp
Navigationと 関連UIコンポーネント 導入振り返り 2019年8月19日 樫村 実紅(かしむら みく) Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
自己紹介 樫村 実紅 @k_miku • 2013 Yahoo! 新卒入社 • Yahoo! ニュース Androidアプリ担当 • B級サメ映画が好き 2 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ナビゲーション導入 日本最大級の ニュースサイトが 速報をお届け 主要 エンタメ スポーツ 予想 地域を設定 > 政府 補助金の使い道検討へ 336 4/29(日)12:12 NEW 最低賃金 地域差拡大は問題か 336 4/29(日)12:22 NEW ふるさと納税 返礼悩む自治体 1500 4/29(日)12:12 「育休3年」は女性にプラスか 456 4/29(日)12:12 シニアに格安スマホ 注意点は 1231 4/29(日)12:12 集めた甲子園の土 今はどこに 1231 4/29(日)12:12 ホーム ライブ ランキング 履歴 ライブ動画 24時間配信 話題の記事を ランキングで 読んだ記事の 履歴を確認 今年5月 Yahoo! ニュースアプリで 下メニューと Navigationを導入 3 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
導入の経緯 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
経緯 アプリの成長に伴い各機能の導線や 関係を整理する必要があった 5 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
技術検討 1. 各画面の遷移をなめらかにしたい ひとつのActivity上でFragment切替するのが良さそう 2. 画面遷移・Fragmentの管理は楽にしたい マテリアルデザインや一般的な実装に追従するため サポートライブラリやJetpackのコンポーネントを利用する 3. 大きい改修時にはなるべく1つ新しい技術に挑戦する 6 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
技術検討 1. 各画面の遷移をなめらかにしたい ひとつのActivity上でFragment切替するのが良さそう 2. 画面遷移・Fragmentの管理は楽にしたい マテリアルデザインや一般的な実装に追従するため サポートライブラリやJetpackのコンポーネントを利用する 3. 大きい改修時にはなるべく1つ新しい技術に挑戦する 7 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Navigationと 関連コンポーネント について Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Navigation <navigation app:startDestination="@+id/main"> <fragment android:id="@+id/main" android:name="package.MainFragment" android:label="MAIN" > <action android:id="@+id/action_main_to_sub" app:destination="@id/sub"/> </fragment> <fragment android:id="@+id/sub" android:name="package.SubFragment" android:label="SUB"> <argument android:name="id" android:defaultValue="1234" app:argType="int" app:nullable="false" /> </fragment> </navigation> XMLでFragmentの階層構造を定義 • Upボタンの挙動 • 画面間の遷移 • Fragmentの引数 などを管理 9 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Navigation GUIでの定義も可能 Destinations Q HOST No NavHostFragments found GRAPH main - Start sub main Preview Unavailable sub Preview Unavailable Attributes Type Action ID action_main_to_su Destination sub ▼ Animations Enter none Exit none Pop Enter none Pop Exit none ▼ Argument Default Values id int default val ▼ Pop Behavior Pop To none Inclusive ▼ Launch Options 10 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Navigation NavigationとNavHostFragmentのみでの実装例 <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:navGraph="@navigation/navigation" /> nav_host_fragment.findNavController().navigate(R.id.action_main_to_sub) 11 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ActionBar・BottomNavigationView 17:43 MAIN MAIN FRAGMENT MAIN SUB 17:43 ← SUB SUB FRAGMENT MAIN SUB Jetpack以前からある Viewコンポーネント Navigationと組み合わせて 利用可能 NavigationViewも仲間ですが 今日は割愛mm 12 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ActionBar・BottomNavigationView 数行のコードでNavigationと関連付け可能 タイトルの表示や画面遷移の実装が簡略化 <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation_view" android:layout_gravity="bottom" android:layout_width="match_parent" app:menu="@menu/menu" android:layout_height="wrap_content"/> val host = nav_host_fragment.findNavController() NavigationUI.setupWithNavController(bottom_navigation_view, host) NavigationUI.setupActionBarWithNavController(activity: this, host) 13 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
課題 これらの連動は便利な機能だが 実際に既存アプリ上で利用するには もどかしい部分もある 14 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ニュースアプリでの事例 YAHOO! ニュース 主要 エンタメ スポーツ 国内 経済 国 東京 28°C / 19°C 朝刊 > 政府 補助金の使い道検討へ 1320 4/29(日)12:12 NEW 最低賃金 地域差拡大は問題か 336 4/29(日)12:12 NEW ふるさと納税 返礼悩む自治体 1500 4/29(日)12:12 「育休3年」は女性にプラスか 456 4/29(日)12:12 シニアに格安スマホ 注意点は 1231 4/29(日)12:12 集めた甲子園の土 今はどこに 1231 4/29(日)12:12 ホーム ライブ ランキング 履歴 1. アクションバーのカスタマイズ 2. 画面遷移アニメーション 3. 画面遷移時の他の処理 15 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ケース1 アクションバー連動時にロゴや 動的な文字列を表示したい Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
アクションバーとの連動 XMLに定義した固定文字列 ロゴ画像・検索フォーム 動的な文字列 「←」以外のUpボタン表示 17:43 ← SUB 17:53 YAHOO! ニュース 17:53 ← 台風10号、西日本に接近の... 17:52 ← Q キーワードを入力 17 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
アクションバーとの連動 1つでもカスタマイズが 必要な画面がある場合 ActionBarとの連動の利用は厳しい // Navigationと連動させてないので各画面で指定 (activity as? AppCompatActivity)?.supportActionBar?.apply { setDisplayShowTitleEnabled(false) // タイトル非表示 setDisplayUseLogoEnabled(true) // ロゴ表示 setLogo(R.drawable.ico_menu_logo) } 18 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ケース2 画面遷移アニメーションの カスタマイズ Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
下タブ連動時のアニメーション
NavigationUI.setupWithNavController(view, host)
を利用する場合の遷移アニメーションは固定。。。
75
76
77
78
79
80
81
82
83
@SuppressWarnings("WeakerAccess") /* synthetic access */
static boolean onNavDestinationSelected(@NonNull MenuItem item,
@NonNull NavController navController, boolean popUp) {
NavOptions.Builder builder = new NavOptions.Builder()
.setLaunchSingleTop(true)
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim);
https://github.com/aosp-mirror/platform_frameworks_support/blob/androidx-1.0-
dev/navigation/ui/src/main/java/androidx/navigation/ui/NavigationUI.java
20
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
下タブ連動時のアニメーション
変更したい場合は自分で遷移処理の実装が必要
// 下メニュー選択時
bottom_navigation_view.setOnNavigationItemSelectedListener { item ->
// 自前でアニメーション指定
val navOptions: NavOptions = NavOptions.Builder()
.setEnterAnim(R.anim.abc_slide_in_top)
.setExitAnim(R.anim.abc_slide_out_top)
.setPopEnterAnim(R.anim.abc_slide_in_bottom)
.setPopExitAnim(R.anim.abc_slide_out_bottom)
.build()
nav_host_fragment.findNavController().navigate(item.itemId, Bundle(), navOptions)
return@setOnNavigationItemSelectedListener true
}
21
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ケース3 画面遷移時に 他の処理を行いたい Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
画面遷移時の割り込み処理 ユーザー行動のログ記録など ケース2同様、自動連動時にはイベントのフックができない 検討1: TouchListenerで代用 検討2: 下メニューとの連動を自分で行う 23 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
NavigationUIと同様の処理を実装...
323
324
325
326
327
328
329
330
331
332
333
public static void setupWithNavController(
@NonNull final BottomNavigationView bottomNavigationView,
@NonNull final NavController navController) {
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
return onNavDestinationSelected(item, navController, true);
});
navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {
// 下メニュー選択時
bottom_navigation_view.setOnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.main -> { } // todo ログ記録などの処理
R.id.sub -> { } // todo ログ記録などの処理
}
NavigationUI.onNavDestinationSelected(item, navController) ^setonNa
}
https://github.com/aosp-mirror/platform_frameworks_support/blob/androidx-1.0-
dev/navigation/ui/src/main/java/androidx/navigation/ui/NavigationUI.java
24
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
まとめ Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
まとめ BottomNavigation / ActionBar / NavigationView と連動させることを目的に Navigationの導入を検討している場合は 要件を満たせるか事前調査しよう 26 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
まとめ • もちろんNavigation単体で 得られるメリットもある • 連動せずに利用することも可能 • 独自処理が必要な場合は 実装のデメリットとメリットを比較する 27 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.