ページをめくるようにアプリ画面全体を変えたり、設定画面、HELPに画面遷移させたいケースは多々あります。
またその時に何らかのデータも同時に転送して、場合によっては遷移先からデータを取得して戻りたい場合の実装方法について考えてみます。
2024.1.1
Activity 画面を遷移しデータを受け渡すアプリ
画面の遷移だけのケースはActivityの画面遷移にて説明しましたが
- 遷移したタイミングでデータを渡したい
- 遷移先から戻るタイミングでデータを受け取りたい
という場合にはIntentを使ってActivity間でデータを渡すことができます。
以前は、startActivityForResult(Intent, int)やonActivityResult(int, int, Intent)
これらを使っていましたが registerForActivityResult() を使うことが推奨されています。
アクティビティの結果を取得する
1. MainActivity :putExtra & registerForActivityResult
2. SubActivity :データを受け取る
3. SubActivity :[back] ボタンのタップで元に戻り、データを返す
4. MainActivity :元の画面でデータを受け取る
5. サンプルコード
putExtra & registerForActivityResult()
MainActivity から SubActivity への遷移は
1 2 |
Intent intent = new Intent(getApplication(), SubActivity.class); startActivity(intent); |
でしたが、ここでデータを渡すために
putExtra(name, value) を追加します
渡すデータの key(name) と value を putExtra に入れます
入れるデータの型指定はありません
1 2 3 |
Intent intent = new Intent(getApplication(), SubActivity.class); intent.putExtra("EXTRA_DATA", data1); startActivity(intent); |
Googleのドキュメント、別の Activity を開始する ではpublicなKeyを設定しています。これはputExtraのReferenceによると
String: The name of the extra data, with package prefix.
とありますので、package名(この例では testactuvitytransdata)をprefixとして例えば、EXTRA_DATAというのを設定します。
1 2 3 4 5 6 |
public static final String EXTRA_DATA = "com.example.testactivitytransdata.DATA"; ... Intent intent = new Intent(getApplication(), SubActivity.class); intent.putExtra(EXTRA_DATA, data1); startActivity(intent); |
data1 を渡すだけならこれでいいのですが、SubActivity からの返しを受け取りたい場合は
registerForActivityResult() を使います。
1 2 3 4 5 6 7 8 9 10 |
ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == Activity.RESULT_OK) { ... } } }); |
1 2 3 4 |
Intent intent = new Intent(getApplication(), SubActivity.class); intent.putExtra(EXTRA_DATA, data1); resultLauncher.launch(intent); |
registerForActivityResult() は、
ActivityResultContract と
ActivityResultCallback を受け取り
他のアクティビティを開始するために使用する
ActivityResultLauncher を返します。
SubActivity データを受け取る
渡されたデータを受け取るには
1 2 |
Intent intent = getIntent(); data1 = intent.getIntExtra(MainActivity.EXTRA_DATA, 0); |
受け取るときは、name とデータの型を指定します。
データが int の場合は、初期値を入れます
intent.getIntExtra(name, defaultValue)
その他、
getStringExtra(String name)
getBooleanExtra(String name, boolean defaultValue)
…etc.
Intent reference
[back] ボタンタップで元に戻り、データを返す
SubActivity から戻るときにデータを返すには同様に
putExtra(name, value)
を使います
1 2 3 |
Intent intent = new Intent(); intent.putExtra(MainActivity.EXTRA_DATA, result); setResult(RESULT_OK, intent); |
元の画面でデータを受け取る
SubActivity から ActivityResultLauncher でデータを受け取り、
RESULT_OKであるか判定してデータを受け取ります。
1 2 3 4 5 6 7 8 9 10 |
ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == Activity.RESULT_OK) { ... } } }); |
サンプルコード
色々追加して、以下のような機能でまとめてみます。
MainActivityで文字入力
SubActivityで受け取って表示
SubActivityから、受け取った文字列に追加して戻す
MainActivityではSubActivityから戻された文字列を表示
尚、Key nameはEXTRA_MESSAGEとして設定しました
MainActivity.java
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 |
//package com.example.testactivitytransdata; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import androidx.activity.EdgeToEdge; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; public class MainActivity extends AppCompatActivity { private EditText editText; private String message; private TextView textView; // the key constant public static final String EXTRA_MESSAGE // YourPackageName.MESSAGE = "com.example.testactivitytransdata.MESSAGE"; ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { //new ActivityResultCallback() { // @Override // public void onActivityResult(ActivityResult result) { if (result.getResultCode() == Activity.RESULT_OK) { Intent intent = result.getData(); if (intent != null) { String res = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); textView.setText(res); } } // } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); textView = findViewById(R.id.text_view); final EditText editText= findViewById(R.id.edit_text); Button button = findViewById(R.id.send_button); button.setOnClickListener( v -> { Intent intent = new Intent(getApplication(), SubActivity.class); if(editText.getText() != null){ String str = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, str); } resultLauncher.launch(intent); // in order to clear the edittext editText.setText(""); }); } } |
遷移先のActivity
SubActivity.javaを作成します。
SubActivity.java
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.testactivitytransdata; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import android.content.Intent; import android.os.Bundle; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class SubActivity extends AppCompatActivity { private EditText editText; private String message; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_sub); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.sub), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); // to get message from MainActivity Intent intentMain = getIntent(); message = intentMain.getStringExtra(MainActivity.EXTRA_MESSAGE); TextView textView = findViewById(R.id.text_view); textView.setText(message); editText = findViewById(R.id.edit_text); // back to MainActivity Button button = findViewById(R.id.back_button); button.setOnClickListener(v -> { Intent intentSub = new Intent(); if (editText.getText() != null) { String str = message + editText.getText().toString(); intentSub.putExtra(MainActivity.EXTRA_MESSAGE, str); } editText.setText(""); setResult(RESULT_OK, intentSub); finish(); }); } } |
Manifest に SubActivity の記述も忘れずに。
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <application ... </activity> <activity android:name=".SubActivity" > </activity> </application> </manifest> |
その他のレイアウト等のファイルは以下です
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のレイアウト
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">YourAppName</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> |
関連ページ:
- アプリの画面を遷移させる
- アプリの画面遷移とActivity間のデータ転送
- グローバル変数を使ってActivity間でデータを渡す
- Activity Life Cycle と画面回転