アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Android版いこーよの中身。Jetpack Navigation編

Androidアプリエンジニアのhondaです。

Android版いこーよではNavigation componentを導入しています。 今回はNavigation componentで画面遷移を実装している際のTIPSを紹介したいと思います。 このブログではNavigation componentについては深く説明しません。 Navigation componentについては下記の公式ページを御覧ください。

developer.android.com

NavigationのstartDestinationを切り替える

Android版いこーよでは今まで1画面1Activityという構成で作られていました。 Navigation componentのstableとなる1.0.0がリリースされてから新規機能などで追加される画面からNavigation componentを導入しています。 今年の初旬にいこーよではいこーよプレミアムという機能がリリースされました。Androidでも実装され、その部分でNavaigation componentも使われています。 iko-yo.net

いこーよプレミアムの場合、プレミアム未加入と加入済みで機能としての最初の画面を切り替える必要がありました。 f:id:kou_hon:20210622064852p:plain これを解決するために今回はプレミアム画面表示時にNavigation componentのナビゲーショングラフのstartDestinationを動的に変更する方法をとりました。

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(this.viewBinding.root)

        val startDestinationId = this.intent.getIntExtra("startDestinationId", 0)
        val navController = this.supportFragmentManager.findFragmentById(R.id.fragmentContainerView)!!.findNavController()
        val navGraph = this.navController.navInflater.inflate(R.navigation.premium_navigation)
        navGraph.startDestination = startDestinationId
        navController.setGraph(navGraph)
    }
}

上記コードの用にまずはナビゲーショングラフが設定されるFragmentContainerViewからNavControllerを取得します。 次に取得したNavControllerからナビゲーショングラフのリソースIDを元にNavGraphを取得します。 最後にNavGraphのstartDestinationに遷移先のFragmentIDを設定して、NavControllerに対してNavGraphを再設定します。 これでSampleActivityを呼び出す側のActivityから画面を切り替えることができるようになりました。

Upボタンを表示させたい

あと、今回仕様としてプレミアム機能の画面でstartDestinationとなる画面でもUPボタンを表示したいというものがありました。 素直に実装するとstartDestinationとなる画面にはUPボタンが表示されません。

f:id:kou_hon:20210625094957p:plain:w250

Upボタンを表示するために以下の方法をとりました。

class SampleFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val toolbar = view.findViewById<MaterialToolbar>(R.id.toolbar)
        val navController = this.findNavController()
        val appBarConfiguration = AppBarConfiguration.Builder(emptySet())
            .setFallbackOnNavigateUpListener {
                this.requireActivity().finish()
                true
            }
            .build()
        toolbar.setupWithNavController(navController, appBarConfiguration)
    }
}

ポイントはAppBarConfiguration.Builderの引数でemptySet()を渡しているところです。 AppBarConfiguration.Builderの引数でFragmentIDを渡すと渡されたFragmentIDをトップレベル画面と判断して、UPボタンが表示されなくなります。 なのでここでemptySet()を渡すことでどの画面でもUPボタンが表示されるようになります。 最後にsetFallbackOnNavigateUpListenerでSampleActivityをfinishして呼び出し側のActivityに戻るようにします。

現場からは以上です。