Android Kotlin基礎講座 03.3: 外部のアクティビティを起動する
目次
タスク:引数を追加・渡す
このタスクでは、型付けされた引数をgameWonFragmentに追加し、それをGameFragmentDirectionsメソッドに渡します。その後、他のフラグメントクラスをそれに対応するNavDirectionクラスで置き換えます。
ステップ1:gameWonFragmentに引数を追加する
- res > navigationフォルダーからnavigation.xmlを開いてください。Designタブをクリックしてナビゲーショングラフを開いてください。
- プレビュー内のgameWonFragmentを選択してください。
- アトリビュートパネルのArgumentsセクションを展開してください。
- +アイコンをクリックして引数を追加してください。名前をnumQuestionsとし、TypeはIntegerを選択してAddをクリックしてください。この引数はユーザーが回答した問題の数を表します。
- gameWonFragmentを選択した状態のまま、二つ目の引数を追加します。名前をnumCorrectとし、TypeはまたIntegerにしてください。この引数はユーザーが正確に答えた問題の数です。
この状態でビルドしようとすると、以下のようなコンパイルエラーが発生します。
No value passed for parameter 'numQuestions'
No value passed for parameter 'numCorrect'
これらのエラーは次のステップで解消します。
Note: Android Studio3.2以下を使用している場合、navigation.xmlファイルのapp:type = “integer”からapp:argType = “integer”に変更する必要があります。
ステップ2:引数を渡す
このステップではnumQuestionsとquestionIndex引数をGameFragmentDirectionsクラスのactionGameFragmentToGameWonFragment()メソッドに渡します。
- GameFragment.ktを開き、ゲームクリア条件文の場所を見てください。
else {
// We've won! Navigate to the gameWonFragment.
view.findNavController()
.navigate(GameFragmentDirections
.actionGameFragmentToGameWonFragment())
}
- numQuestionsとquestionIndexをactionGameFragmentToGameWonFragment()メソッドに渡してください。
// Adding the parameters to the Action
view.findNavController()
.navigate(GameFragmentDirections
.actionGameFragmentToGameWonFragment(numQuestions, questionIndex))
合計の問題数をnumQuestionsとして、現在取りくんでいる問題をquestionIndexとして渡します。アプリはユーザーが全ての問題を正確に答えた時のみデータを共有できるようにデザインされます。したがって、正確に答えた数は常に回答した問題の数と一致します。
- GameWonFragment.ktで、bundleから引数を抽出し、その引数をトーストで表示するために使います。以下のコードをonCreateView()メソッドのreturn文の前に追加してください。
val args = GameWonFragmentArgs.fromBundle(arguments!!)
Toast.makeText(context, "NumCorrect: ${args.numCorrect}, NumQuestions: ${args.numQuestions}", Toast.LENGTH_LONG).show()
- アプリを起動して、引数がしっかりGameWonFragmentに渡されているかを確認するためにゲームをプレイしてみてください。Congratulations画面で”NumCorrect: 3, NumQuestions: 3″と表示するトーストメッセージが表示されます。
このメッセージを表示するためにはまずゲームをクリアする必要があります。GameFragment.ktのnumQuestionsの値を1に設定することで、問題数を1にし、ゲームを簡単にすることができます。
型安全を使う際、フラグメントクラスの画面遷移に利用されているコードをNavDirectionクラスで置き換えることができます。これをすることによって、型安全な引数をアプリの他のフラグメントでも利用できるようになります。
TitleFragment、GameFragment、GameWonFragment内のnavigate()メソッドに渡されているアクションIDを変更します。アクションIDを適切なNavDirectionクラスの同等のメソッドで置き換えます。
- TitleFragment.ktを開いてください。onCreateView()内のPlayボタンのクリックハンドラーの中のnaigate()メソッドの部分を見てください。メソッドの引数にTitleFragmentDirections.actionTitleFragmentToGameFragment()を渡してください。
binding.playButton.setOnClickListener { view: View ->
view.findNavController()
.navigate(TitleFragmentDirections.actionTitleFragmentToGameFragment())
}
- 同様にGameOverFragment.ktのTryAgainボタンのクリックハンドラーに
GameOverFragmentDirections.actionGameOverFragmentToGameFragment()をnavigate()メソッドの引数に渡してください。
binding.tryAgainButton.setOnClickListener { view: View ->
view.findNavController()
.navigate(GameOverFragmentDirections.actionGameOverFragmentToGameFragment())
}
- 同様にGameWonFragment.ktのNext Matchボタンのクリックハンドラーに
GameWonFragmentDirections.actionGameWonF
binding.nextMatchButton.setOnClickListener { view: View ->
view.findNavController()
.navigate(GameWonFragmentDirections.actionGameWonFragmentToGameFragment())
}
- アプリを起動してください。
アプリの挙動に変化は見られませんが、内部ではNavDirectionクラスを使った引数をどこでも簡単に渡せるようになっています。