画面の移動(Intent)

(ブログ記事の一覧は「こちら」)

スマホアプリで普通に行われている、画面の移動の方法について学びます。
Androidアプリでは、Intentクラスを用いることで、Activityの移動が実現できます。

ここで学ぶこと

  • メイン画面(MainActivity)からサブ画面(SubActivity)への移動
  • メイン画面からサブ画面へのパラメータの受け渡し
  • サブ画面からメイン画面へのパラメータの受け渡し

例題1

まず、メイン画面(MainActivity)からサブ画面(SubActivity)へのシンプルな移動を行います。

作成するもの

  • メイン画面のボタンをクリックすると、サブ画面に移動する
  • サブ画面のボタンをクリックすると、(サブ画面が終了して)メイン画面に戻る

準備

プロジェクトにサブ画面(SubActivity)を追加します。
Android Studioで、以下のメニューを選択します。
[File] - [New] - [Activity] - [Empty Activity]

「SubActivity」と入力してFinishボタンを押すと、レイアウトファイル(activity_sub.xml)も自動的に生成されます。
また、マニフェストファイル(AndroidManifest.xml)も自動的に更新されています。中身を確認しておきましょう。


レイアウト(メイン画面)

activity_main.xmlは以下のように作成しました。
この例題1では、必要なコントロールはButtonだけですが、例題2で使用するEditTextとTextViewもここで用意しておきます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="次の画面"/>
</LinearLayout>

プログラム(メイン画面)

ボタンをクリックすると、サブ画面に移動するプログラム例です。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // SubActivityの呼び出し
                Intent intent = new Intent(MainActivity.this, SubActivity.class);
                startActivity(intent);
            }
        });
    }
}


レイアウト(サブ画面)

activity_sub.xmlは以下のように作成しました。
こちらも同じく、この例題1では、必要なコントロールはButtonだけですが、例題2で使用するEditTextとTextViewも用意しておきます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:orientation="vertical"
    tools:context=".SubActivity">

    <EditText
        android:id="@+id/editText_sub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/textView_sub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button_sub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="戻る"/>
</LinearLayout>

プログラム(サブ画面)

ボタンをクリックすると、(サブ画面が終了して)メイン画面に戻るプログラム例です。

public class SubActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);

        Button button = findViewById(R.id.button_sub);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // SubActivityの終了
                finish();
            }
        });
    }
}


実行、確認

それぞれの画面のボタンをクリックすると、それぞれ画面が切り替わることが確認できます。

例題2

以下の動作を実現するように、プログラムを修正します。

  • メイン画面からサブ画面へのパラメータの受け渡し
  • サブ画面からメイン画面へのパラメータの受け渡し

新しい内容が多いため、今回は正解例を載せておきます。例題のプログラムと比較して、違いが説明できるようにしてください。

プログラム(メイン画面)

ボタンをクリックしたとき、画面の移動に加えて、EditTextに入力したテキストをサブ画面に送ります。
また、新たに追加されているonActivityResult関数内で、サブ画面のEditTextで入力したテキストをメイン画面のTextViewに表示する処理も行っています。
(onActivityResult関数は、メニューの [Code] -[Override Methods...] から記述できます。)

public class MainActivity extends AppCompatActivity {

    private final static int REQUEST_MAIN = 0; // テキストID

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                EditText editText = findViewById(R.id.editText);

                // SubActivityの呼び出し
                Intent intent = new Intent(MainActivity.this, SubActivity.class);
                // Intentへのパラメータ指定
                intent.putExtra("TEXT_FOR_SUB", editText.getText().toString());
                startActivityForResult(intent, REQUEST_MAIN);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == REQUEST_MAIN) {
                // SubActivityのIntentからのパラメータ取得
                String strText = "";
                Bundle extras = data.getExtras();
                if (extras != null) strText = extras.getString("TEXT_FOR_MAIN");

                TextView textView = findViewById(R.id.textView);
                textView.setText(strText);
            }
        }
    }
}

プログラム(サブ画面)

メイン画面から送られたテキストをTextViewに表示しています。
また、ボタンをクリックしたとき、画面の移動に加えて、EditTextに入力したテキストをメイン画面に送ります。

public class SubActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);

        // MainActivityのIntentからのパラメータ取得
        String strText = "";
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            strText = extras.getString("TEXT_FOR_SUB");
        }

        TextView textView = findViewById(R.id.textView_sub);
        textView.setText(strText);

        Button button = findViewById(R.id.button_sub);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                EditText editText = findViewById(R.id.editText_sub);

                // 戻り値の指定
                Intent intent = new Intent();
                intent.putExtra("TEXT_FOR_MAIN", editText.getText().toString());
                setResult(RESULT_OK, intent);

                // SubActivityの終了
                finish();
            }
        });
    }
}

実行、確認

それぞれの画面のEditTextに入力して、画面の移動を行ってください。
どのプログラムが、どの動作に関係しているか、確認してください。

課題1

例題1に対して、さらに追加のサブ画面(Sub2Activity)を追加して、以下の画面の移動ができるように、プログラムを修正してください。

メイン画面(MainActivity)→ サブ画面(SubActivity)→ サブ2画面(Sub2Activity)

課題2

一般的なツールアプリでは、サブ画面は設定画面のような使い方ができるとみなせます。

例題2に対して、プリファレンスを使用して、メイン画面(MainActivity)とサブ画面(SubActivity)のそれぞれのEditTextに対して、入力した内容が保存されるようにプログラムを修正してください。