😺

Navigationで遷移先画面からパラメータを受け取る

2020/09/29に公開

Noteの記事を加筆修正しました

youtubeこの動画を見ていたらNavigation2.3から戻り値を返して画面を戻る事ができると知ったので動画のログインサンプルを写経しました。

ログイン後しか見れないFragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val navController = findNavController()
    val stateHandle = navController.currentBackStackEntry!!.savedStateHandle
    stateHandle.getLiveData<Boolean>(LoginFragment.LOGIN_SUCCESSFUL)
        .observe(viewLifecycleOwner, Observer { success ->
            if (success) {
                loadData()
            } else {
                val startDistination = navController.graph.startDestination
                navController.navigate(startDistination, null, navOptions {
                    popUpTo(startDistination) {
                        inclusive = true
                    }
                })
            }
    })

    if (!(activity as MainActivity).getIsLogin()) {
        navController.navigate(R.id.action_mainFragment_to_loginFragment)
    }
}

こちらはログイン後のみアクセス可能なFragmentです。

    if (!(activity as MainActivity).getIsLogin()) {
        navController.navigate(R.id.action_mainFragment_to_loginFragment)
    }

この部分でログイン済みかどうかを判定しています。
本来であればViewModel->Repositoryを使ってログイン判定を行う事が多いと思います。

stateHandle.getLiveData<Boolean>(LoginFragment.LOGIN_SUCCESSFUL)

こちらが遷移先のログイン画面から戻り値を受け取る部分です。
LiveDataで受け取れるのでObserveしてあげればOKです。

LoginFragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val navController = findNavController()
    val savedStateHandle = navController.previousBackStackEntry!!.savedStateHandle

    view.findViewById<Button>(R.id.button).setOnClickListener {
        savedStateHandle.set(LOGIN_SUCCESSFUL, true)
        navController.popBackStack()
    }
    view.findViewById<Button>(R.id.button3).setOnClickListener {
        savedStateHandle.set(LOGIN_SUCCESSFUL, false)
        navController.popBackStack()
    }
}

こちらはログイン処理を行うFragmentです。
が、今回はログイン成功ボタンとログイン失敗ボタンを用意し、
それぞれ結果をセットしてログイン後にしか見れないFragmentへ戻る事にしました。

savedStateHandle.set(LOGIN_SUCCESSFUL, true)
navController.popBackStack()

ここで前の画面に渡すキーと値をセットして前の画面に戻っています。

サンプルコード

https://github.com/sobaya-0141/AllFlow/tree/login

Discussion