はじめに
Android の画面は基本的に1画面1 Activity だと思うが Activity = UIViewController だと思うのはちょっと危険な気がする。
Activity 間はゆる〜く関係し合ってはいるがほとんど独立したものと考えた方がいいかもしれない。他アプリから指定の Activity 起動もできるので Web ページに近いかもしれない。なんにしろ UIViewController とは別の何かだと思っておいた方がよさそう。(Context さえあれば Activity 以外からも Activity は呼べる)
今回はそんな Activity の画面遷移について書きます。
Navigation はこっち
アプリ内遷移
Activity 間の遷移には Intent を利用します。Activity の遷移には startActivity()
と startActivityForResult()
の2つがあります。
startActivity
遷移先 Activity から遷移元 Activity に結果を返す必要がない場合はこちらを利用します。
遷移処理
1 2 |
val intent = Intent(this, SecondActivity::class.java) startActivity(intent) |
値を渡す場合
1 2 3 4 5 6 7 8 |
// 遷移元 val intent = Intent(this, SecondActivity::class.java).apply { putExtra("hoge_key", "hoge") } startActivity(intent,) // 遷移先(onCreateとかで) val hoge = intent.getStringExtra("hoge_key") |
startActivityForResult
遷移先 Activity から遷移元 Activity に結果を返す場合はこちらを利用します。
遷移処理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// 遷移元 companion object { // リクエストコードを定義しておく private val REQUEST_HOGE = 0 } val intent = Intent(this, SecondActivity::class.java).apply { putExtra("hoge_key", "hoge") } startActivityForResult(intent, REQUEST_HOGE) // ここで値受け取る override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUEST_HOGE -> if (resultCode == RESULT_OK) { val piyo = data?.getStringExtra("piyo_key") } } } // 遷移先(onCreateとかで) val hoge = intent.getStringExtra("hoge_key") val button = findViewById<Button>(R.id.button) button.setOnClickListener { val data = Intent().apply { putExtra("piyo_key", "piyo") } // 値設定 setResult(RESULT_OK, data) finish() } |
戻るボタンなどでsetResult()
を呼ばずに遷移元に戻った場合は resultCode
は RESULT_CANCELED
になる。
他アプリ間の遷移
マニフェストファイルで指定の Activity にインテントフィルタを設定しておくと他アプリから Activity を起動することもできる。
1 2 3 4 5 6 7 |
<activity android:name="HogeActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> </activity> |
表示
1 2 3 4 5 6 7 |
val intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "hoge") type = "text/plain" } val shareIntent = Intent.createChooser(intent, null) startActivity(shareIntent) |
上記のように Android Sharesheet を利用した方がいいらしい。
アクション指定でやるのは暗黙的インテント、アクティビティの名前まで指定するのは明示的インテントというらしい。明示的インテントは基本的に同一アプリ内でしか使わない模様。
参考
余談
Activity はすべてマニフェストファイルに記載する必要があり書いてないと下記のようなエラーになる。
1 |
android.content.ActivityNotFoundException: Unable to find explicit activity class ~ |
アプリ起動時に表示する Activity には下記のようにインテントフィルタを設定する。
1 2 3 4 |
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> |
さいごに
Android の難関は Intent と Activity だと思う。ViewController 感覚で Activity を利用してしまうと痛い目にあう(ライフサイクルとか)。。。
Java だけど下記記事が参考になる気がした。
Androidの画面設計や遷移に関して整理してみる
コメント