問題
例えば、AAC Navigationのnavigate()するボタンを2つ同時に押すなどした時に以下のように怒られクラッシュする。
2020-02-13 15:24:08.709 21427-21427/jp.studysapuri.for_school.dev.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: jp.studysapuri.for_school.dev.debug, PID: 21427
java.lang.IllegalArgumentException: navigation destination jp.studysapuri.for_school.dev.debug:id/action_mypageFragment_to_searchSchoolByConditionFragment is unknown to this NavController
原因
navigate()が2つ同時に実行された場合、2つ目の実行時には現在の画面(ナビゲーションgraphのnode)が1つ目の遷移先になっているため、画面に紐つくactionが無いことになってしまう。
回避策
今いるnode(画面)に紐つくactionが有るかを確認しあればnavigate()を実行、なければ何もしないようにするような拡張関数(以下の例ではnavigateSafe())を作り、navigate()の代わりに使う。
import android.os.Bundle
import androidx.annotation.IdRes
import androidx.navigation.*
fun NavController.navigateSafe(
@IdRes resId: Int,
args: Bundle? = null,
navOptions: NavOptions? = null,
navExtras: Navigator.Extras? = null
) {
val action = currentDestination?.getAction(resId) ?: graph.getAction(resId)
if (action != null && currentDestination?.id != action.destinationId) {
navigate(resId, args, navOptions, navExtras)
}
}
fun NavController.navigateSafe(
node: NavDirections,
navOptions: NavOptions? = null
) {
val action = currentDestination?.getAction(node.actionId) ?: graph.getAction(node.actionId)
if (action != null && currentDestination?.id != action.destinationId) {
navigate(node, navOptions)
}
}