【Android開発】 明示的インテントを使っての画面遷移とActivity間のデータ転送
今回作るアプリ
明示的インテントを使って画面遷移を行います。
また遷移するときにデータの受け渡しをします。
サンプルアプリの構成は下記になります。
MainActtivityとSecondActivity、2つのActivityを含むアプリを作成します。
MainActtivityには編集テキストと送信ボタンが含まれています。
ユーザーはメッセージを入力して送信ボタンをクリックします。
MainActtivityはインテントを使用してSecondActivityを開始し、MainActtivityで入力したメッセージをSecondActivityに送信します。
SecondActivityでは受信したメッセージが表示されます。
動作環境
Android Studio4.1
windows10
実装手順
プロジェクト構成
以下の内容でプロジェクトを作ります。
名前:IntentActivity
言語:Java
最小SDK:API19
サンプルコード
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_main"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:onClick="goSecondActivity"
android:text="Go Second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/editText_main"
app:layout_constraintTop_toTopOf="@+id/editText_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
Button#onClick属性のgoSecondActivity()メソッドはまだ実装していないため、赤の下線が引かれています。
「goSecondActivity」をクリックしてAlt+Enterを押し、「作成 'goSecondActivity(View)' in 'MainActivity'」を選択します。
MainActivity.javaにgoSecondActivity()メソッドが生成します。
SecondActivityを作成します。
プロジェクトのアプリフォルダをクリックし、ファイル > 新規作成 > アクティビティ > 空のアクティビティを選択します。
アクティビティ名を「SecondActivity」にしてGenerate a Layout Fileのチェックを入れた状態で完了をクリックします。
「SecondActivity.java」と「activity_second.xml」が生成されます。
またAndroidManifest.xmlにSecondActivityが追加されていることを確認します。
<activity android:name=".SecondActivity"></activity>
SecondActivityのレイアウトを作ります。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<TextView
android:id="@+id/title_second_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="Message from Main Activity"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/message_from_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_second_activity" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivityに明示的インテントを追加します。
このインテントはボタンをクリックしたときにSecondActivityに遷移します。
以下のようにMainActivity.javaに明示的インテントを追加します。
public class MainActivity extends AppCompatActivity {
// インテントエクストラの公開キー
// 接頭辞としてアプリのパッケージ名を含める
public static final String EXTRA_MAIN_MESSAGE =
"com.example.intentactivity.EXTRA_MAIN_MESSAGE";
private EditText mEditText_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText_main = findViewById(R.id.editText_main);
}
public void goSecondActivity(View view) {
// 入力した文字列を取得
String message = mEditText_main.getText().toString();
/*
インテントコンストラクタ
第1引数 呼び出し元のコンテキスト
第2引数 呼び出し先のクラスを指定
*/
Intent intent = new Intent(this, SecondActivity.class);
// データを渡す設定
intent.putExtra(EXTRA_MAIN_MESSAGE, message);
// SecondActivityを呼び出す
startActivity(intent);
}
}
SecondActivityでインテントを受け取り、受け取ったデータを画面に表示します。
private TextView mMessageFromMainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
// メインアクティビティからのインテントを受け取る
Intent intent = getIntent();
// メインアクティビティからのメッセージを取得
String message = intent.getStringExtra(MainActivity.EXTRA_MAIN_MESSAGE);
mMessageFromMainActivity = findViewById(R.id.message_from_main_activity);
mMessageFromMainActivity.setText(message);
}
アプリを実行します。MainActivityにメッセージを入力してボタンをクリックすると、SecondActivityが起動してメッセージが表示されます。
SecondActivityからMainActivityへデータを渡す
最後にSecondActivityからMainActivityへデータを渡すようにアプリを変更します。
最初に使用する文字列をstrings.xmlに定義しておきましょう。
<resources>
<string name="app_name">IntentActivity</string>
<string name="message_from_second_activity">Message from Second Activity</string>
<string name="message_from_main_activity">Message from Main Activity</string>
<string name="go_main">Go Main</string>
<string name="go_second">Go Second</string>
</resources>
activity_second.xmlにEditTextとButton要素を追加して以下のように変更します。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<TextView
android:id="@+id/title_second_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/message_from_main_activity"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/message_from_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_second_activity" />
<EditText
android:id="@+id/editText_second"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:inputType="text"
app:layout_constraintEnd_toStartOf="@id/btn_main"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_from_main_activity" />
<Button
android:id="@+id/btn_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:onClick="goMainActivity"
android:text="@string/go_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/editText_second"
app:layout_constraintTop_toTopOf="@+id/editText_second" />
</androidx.constraintlayout.widget.ConstraintLayout>
Button#onClick属性のgoMainActivity()メソッドはまだ実装していないため、赤の下線が引かれています。
「goMainActivity」をクリックしてAlt+Enterを押し、「作成 'goMainActivity(View)' in 'SecondActivity'」を選択します。
SecondActivity.javaにgoMainActivity()メソッドが生成します。
SecondActivity.javaを以下のように変更します。
public class SecondActivity extends AppCompatActivity {
// インテントエクストラの公開キー
// 接頭辞としてアプリのパッケージ名を含める
public static final String EXTRA_SECOND_MESSAGE =
"com.example.intent.EXTRA_SECOND_MESSAGE";
private TextView mMessageFromMainActivity;
private EditText mEditTextSecond;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mEditTextSecond = findViewById(R.id.editText_second);
// メインアクティビティからのインテントを受け取る
Intent intent = getIntent();
// メインアクティビティからのメッセージを取得
String message = intent.getStringExtra(MainActivity.EXTRA_MAIN_MESSAGE);
mMessageFromMainActivity = findViewById(R.id.message_from_main_activity);
mMessageFromMainActivity.setText(message);
}
public void goMainActivity(View view) {
String message = mEditTextSecond.getText().toString();
// レスポンス用の新しいインテントを作成する
Intent intent = new Intent();
// EditTextから取得したデータをエクストラとしてインテントに追加
// キーと値のペアを指定する
intent.putExtra(EXTRA_SECOND_MESSAGE, message);
// 結果コードとデータをセットする
setResult(RESULT_OK, intent);
// アクティビティを閉じてMainActivityに戻る
finish();
}
}
MainActivityをSecondActivityから渡されたデータを受け取れるように変更します。
activity_main.xmlを以下のように変更します。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/title_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/message_from_second_activity"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/message_from_second_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_main_activity" />
<EditText
android:id="@+id/editText_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:inputType="text"
app:layout_constraintEnd_toStartOf="@id/btn_main"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/message_from_second_activity" />
<Button
android:id="@+id/btn_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:onClick="goSecondActivity"
android:text="@string/go_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/editText_main"
app:layout_constraintTop_toTopOf="@+id/editText_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
追加したTextViewにはandroid:visibility属性を追加して、最初は見えないようにします。
起動直後は何も表示しないためです。これらの要素はSecondActivityからデータを渡された後に表示します。
TextViewは不可視に設定しているため画面には表示されません。
MainActivity.javaを以下のように変更します。
public class MainActivity extends AppCompatActivity {
// インテントエクストラの公開キー
// 接頭辞としてアプリのパッケージ名を含める
public static final String EXTRA_MAIN_MESSAGE =
"com.example.intentactivity.EXTRA_MAIN_MESSAGE";
// 遷移先のアクティビティを判別するための要求コード
// 任意の整数で指定
private static final int REQUEST_CODE = 1;
private TextView mTitleMainActivity;
private TextView mMessageFromSecondActivity;
private EditText mEditText_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText_main = findViewById(R.id.editText_main);
mTitleMainActivity = findViewById(R.id.title_main_activity);
mMessageFromSecondActivity = findViewById(R.id.message_from_second_activity);
}
public void goSecondActivity(View view) {
// 入力した文字列を取得
String message = mEditText_main.getText().toString();
/*
インテントコンストラクタ
第1引数 呼び出し元のコンテキスト
第2引数 呼び出し先のクラスを指定
*/
Intent intent = new Intent(this, SecondActivity.class);
// データを渡す設定
intent.putExtra(EXTRA_MAIN_MESSAGE, message);
// 遷移先のアクティビティから結果を受け取るため、startActivity()からstartActivityForResult()に変更
startActivityForResult(intent, REQUEST_CODE);
}
/**
* startActivityForResultメソッドで起動された Activity が終了すると、
* onActivityResultメソッドが呼び出されます。
*
* @param requestCode
* startActivityForResult()で指定した要求コード。どこのアクティビティから戻ってきたのかを判別する
*
* @param resultCode
* 呼び出し元のアクティビティに戻ってくる前にどのような処理が行われたのか判別する
*
* @param data
* 呼び出し元のIntentデータ
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
// SecondActivityから戻ってきた処理
if (resultCode == RESULT_OK) {
// SecondActivityのボタンを押して戻ってきたときの処理
// TextView要素を可視化
mTitleMainActivity.setVisibility(View.VISIBLE);
// SecondActivityのインテントからデータを取得
// ExtraのキーはSecondActivityの公開キーになります
String message = data.getStringExtra(SecondActivity.EXTRA_SECOND_MESSAGE);
// 取得したデータをtextviewにセット
mMessageFromSecondActivity.setText(message);
// TextView要素を可視化
mMessageFromSecondActivity.setVisibility(View.VISIBLE);
}
}
}
}
これでSecondActivityからのデータをMainActivityで受け取って表示することができました。
Discussion