KotlinでのActivityの遷移とそれに伴ってデータを別Activityに送る、またそのActivityから何かのデータを受け取る方法について調べてみました。
2024.1.1
Activity 画面を遷移しデータを受け渡すアプリ
画面遷移だけのKotlinのケースは、
にて説明しましたが、
- 遷移したタイミングでデータを渡したい
- 遷移先から戻るタイミングでデータを受け取りたい
という場合にはIntentを使ってActivity間でデータを渡すことができます。
以前は、startActivityForResult(Intent, int)とonActivityResult(int, int, Intent)
これらを使っていましたが
AndroidX Activity と Fragment で導入された Activity Result API を使用すること推奨されています応(Activity クラスでは使用できますが…)アクティビティの結果を取得する
1. MainActivity :putExtra & onActivityResult
2. SubActivity :データを受け取る
3. SubActivity :[back] ボタンのタップで元に戻り、データを返す
4. MainActivity :元の画面でデータを受け取る
5. サンプルコード
MainActivity: putExtra & registerForActivityResult()
MainActivity から SubActivity への遷移は
1 2 |
val intent = Intent(applicationContext, SubActivity::class.java) startActivity(intent) |
別の Activity を開始する ではpublicなKeyを設定しています。これはputExtraによると
String: The name of the extra data, with package prefix.
とありますので、例えばpackage名をprefix(com.example.testactivitytransdata)としてEXTRA_MESSAGEというのを設定します。
1 2 3 |
companion object { const val EXTRA_MESSAGE = "com.example.testactivitytransdata.MESSAGE" } |
このEXTRA_MESSAGEを使って putExtra(name, value) に渡すデータの key(name) と value を入れます
入れるデータの型指定はありません
1 2 3 |
val intent = Intent(applicationContext, SubActivity::class.java) intent.putExtra(EXTRA_MESSAGE, data); startActivity(intent) |
data を渡すだけならこれでいいのですが、SubActivity からの返しを受け取りたいので
1 2 3 4 |
val intent = Intent(applicationContext, SubActivity::class.java) intent.putExtra(EXTRA_MESSAGE, data); getResult.launch(intent) |
registerForActivityResult()で受け取り、返ってくる結果が正常か、またリクエストコードの判定をします。it がActivityResult になります。
1 2 3 4 5 6 7 8 |
val getResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { if (it.resultCode == Activity.RESULT_OK) { val res = it.data?.getStringExtra(EXTRA_MESSAGE) ... } } |
SubActivity: データを受け取る
渡されたデータを受け取るときには、型に合わせてgetString()などを使います
1 |
val message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE) |
name とデータの型を指定します。
データが int の場合は、初期値を入れますがString型ではいりません。
その他、
getBooleanExtra(String name, boolean defaultValue)
…etc.
Intent reference
SubActivity: [back] ボタンタップで元に戻り、データを返す
SubActivity から戻るときにデータを返すには同様に
putExtra(name, value)
を使います
1 2 3 |
val intent = Intent() intent.putExtra(MainActivity.EXTRA_MESSAGE, message) setResult(Activity.RESULT_OK, intent) |
MainActivity: 元の画面でデータを受け取る
SubActivity からのデータを受け取るにはregisterForActivityResult()から、RESULT_OKであるか判定してデータを受け取ります。
1 2 3 4 5 6 7 8 |
val getResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { if (it.resultCode == Activity.RESULT_OK) { val res = it.data?.getStringExtra(EXTRA_MESSAGE) ... } } |
サンプルコード
色々追加して、以下のような機能でまとめてみます。
MainActivityで文字入力
SubActivityで受け取って表示
SubActivityから、受け取った文字列に追加して戻す
MainActivityではSubActivityから戻された文字列を表示
MainActivity.kt
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
//package com.example.kotlinactivitytransdata import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import android.app.Activity import android.content.Intent import androidx.activity.result.contract.ActivityResultContracts import com.example.kotlinactivitytransdata.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { companion object { const val EXTRA_MESSAGE = "com.example.kotlinactivitytransdata.MESSAGE" } private lateinit var binding: ActivityMainBinding private val getResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { if (it.resultCode == Activity.RESULT_OK) { val res = it.data?.getStringExtra(EXTRA_MESSAGE) binding.textView.text = res } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } binding.sendButton.setOnClickListener { if (binding.editText.text != null) { val intent = Intent(applicationContext, SubActivity::class.java) val str = binding.editText.text.toString() intent.putExtra(EXTRA_MESSAGE, str) getResult.launch(intent) binding.editText.setText("") } } } } |
遷移先のActivity
SubActivity.ktを作成し
コードを記述します。
SubActivity.kt
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
//package com.example.kotlinactivitytransdata import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import android.app.Activity import android.content.Intent import com.example.kotlinactivitytransdata.databinding.ActivitySubBinding class SubActivity : AppCompatActivity() { private lateinit var binding: ActivitySubBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivitySubBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.sub)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } // to get message from MainActivity val message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE) binding.textView.text = message binding.backButton.setOnClickListener { val intentSub = Intent() if (binding.editText.text != null) { val str = message + binding.editText.text.toString() intentSub.putExtra(MainActivity.EXTRA_MESSAGE, str) binding.editText.setText("") } setResult(Activity.RESULT_OK, intentSub) finish() } } } |
以下はレイアウトやリソースです
activity_main.xml
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#dfe" tools:context=".MainActivity"> <!-- Top Title--> <TextView android:id="@+id/top_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:gravity="center_horizontal" android:text="@string/main" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> <!-- to send text--> <TextView android:id="@+id/to_sub" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="end" android:text="@string/to_sub" android:textSize="24sp" app:layout_constraintEnd_toEndOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/top_title" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/edit_text" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.05" /> <EditText android:id="@+id/edit_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:autofillHints="@string/hint1" android:background="#fff" android:text="@string/hint1" android:hint="@string/hint1" android:inputType="text" android:textSize="24sp" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/top_title" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.05" /> <!-- returned text--> <TextView android:id="@+id/fm_sub" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="end" android:text="@string/from_sub" android:textSize="24sp" app:layout_constraintEnd_toEndOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/to_sub" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.03" /> <TextView android:id="@+id/text_view" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="@string/message" android:textSize="24sp" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/to_sub" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.03"/> <Button android:id="@+id/send_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:gravity="center" android:text="@string/move" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.45"/> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="180dp" /> </androidx.constraintlayout.widget.ConstraintLayout> |
SubActivityのレイアウト用のxmlファイルを作成
activity_sub.xml
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/sub" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- Top Title--> <TextView android:id="@+id/top_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:gravity="center_horizontal" android:text="@string/sub" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> <!-- received text--> <TextView android:id="@+id/to_sub" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="end" android:text="@string/from_main" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/guideline2" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/edit_text" app:layout_constraintTop_toBottomOf="@+id/top_title" app:layout_constraintVertical_bias="0.05" /> <TextView android:id="@+id/text_view" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="@string/message" android:textSize="24sp" app:layout_constraintStart_toStartOf="@+id/guideline2" app:layout_constraintTop_toBottomOf="@+id/top_title" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.05"/> <!-- send text--> <TextView android:id="@+id/fm_sub" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="end" android:text="@string/to_main" android:textSize="24sp" app:layout_constraintEnd_toEndOf="@+id/guideline2" app:layout_constraintTop_toBottomOf="@+id/to_sub" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.03" /> <EditText android:id="@+id/edit_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="10dp" android:autofillHints="@string/hint2" android:background="#fff" android:text="@string/hint2" android:hint="@string/hint2" android:inputType="text" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintStart_toStartOf="@+id/guideline2" app:layout_constraintTop_toBottomOf="@+id/to_sub" app:layout_constraintVertical_bias="0.03" /> <Button android:id="@+id/back_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:gravity="center" android:text="@string/back" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.45"/> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="180dp" /> </androidx.constraintlayout.widget.ConstraintLayout> |
リソースです
strings.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<resources> <string name="app_name">KotlinActivityTransData</string> <string name="main">Main Activity</string> <string name="sub">Sub Activity</string> <string name="hint1">Message to Sub</string> <string name="hint2">Message to Main</string> <string name="to_main">" to Main"</string> <string name="from_main">"from Main"</string> <string name="to_sub">" to Sub"</string> <string name="from_sub">"from Sub"</string> <string name="move">move</string> <string name="back">back</string> <string name="message">message</string> </resources> |
Manifest に SubActivity の記述も忘れずに、package名は適宜合わせてください。
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <application ... <activity android:name=".MainActivity"> ... </activity> <activity android:name=".SubActivity" > </activity> </application> </manifest> |
View Binding の設定
build.gradle
1 2 3 4 5 6 7 8 |
... android { ... buildFeatures { viewBinding =true } } ... |
References:
アクティビティの結果を取得する | Android デベロッパー | Android
Activity | Android Developers
別の Activity を開始する | Android Developers
Intent | Android Developers