ゲームアプリのメイン画面からステージ画面や設定画面、HELP画面などに移行させたいときにはどうするか。そんなときはActivityの画面遷移を使います。またActivityを変えないで画面を変える方法もあります。
API 30
画面遷移
ここではActivityを使った画面遷移を考えてみますが、場合によってはActivityの画面遷移を使わない方法もあります。
● Activityを変えて別のActivityへ画面遷移
- 画面だけでなく使用する変数も全く異なるActivityへの移行
- Activityの変更のため内部処理が多く、多少の遅れもあり得る
● Fragmentを使用し画面表示を任せる
- Activityは画面管理以外にも色々とtaskがあるので画面の変更だけに使うにはコスト高です。Activityを変えずにFragmentで画面を複数張り付けることが可能です。
FragmentをActivityからコードで設定してHello Worldを表示させてみましたが、今度はActivityからFra...
〇 同一Activityでの画面変更
- 使用する変数は同じだが値が異なる、名簿などで名前、住所などをデータベースから取り出すだけで表示フォーマットは同じ様なケースなど
- Activityの画面遷移に比べて素早くできる(そうなる場合に有効)
- 1つのActivityが複雑な構成になってメンテナンスに支障が出ないように注意
Intent
「Activityを変えて画面遷移」をしたい場合には、Intent を使います。
IntentはActivityやServiceなどのコンポーネントを外部から起動するための仕組みです。他のActivityを起動する方法には次のものがあります。
- startActivity(Intent)
- データを遷移先に転送することもできる
- startActivityForResult(Intent, int)
- データを遷移先に転送
- 遷移先からデータを受け取ることができる
startActivityはその名の通り、Activityを開始させるものです。
startActivityForResult(Intent, int) は、遷移先から結果などのデータを受け取りたい場合で
onActivityResult(int, int, Intent) で受け取ります。
ここでは、画面の基本の遷移だけを扱ってみます。
データを遷移先に渡したり、遷移先からデータを受け取りたい場合は、
アプリの画面遷移とActivity間のデータ転送 を参照してください。
startActivity(Intent)
MainActivity 画面で 「MOVE」 ボタンをタップするとSubActivity 画面に遷移、そこで [RETURN] ボタンのタップでMainActivity に戻る基本的なアプリを作ってみたいと思います。
MainActivity から SubActivity への遷移は
1 2 |
Intent intent = new Intent(MainActivity.this, SubActivity.class); startActivity(intent); |
Intent のインスタンスを、現在のActivityから、遷移先のActivityを引数に入れて生成します。
MainActivity.this, SubActivity.class
と設定して、テストで動かすぐらいであれば問題はないのですが、何度も同じ画面移動が繰り返されると強参照のためメモリがパイルアップし続けてOut of Memoryとなる可能性があります。
状況に応じてgetApplication()などに変更したほうがいいようです
1 2 |
Intent intent = new Intent(getApplication(), SubActivity.class); startActivity(intent); |
SubActivity からの戻りは
Activity を終了させます
1 |
finish(); |
Manifestに SubActivity を追加
1 2 3 4 |
<activity android:name=".SubActivity" android:label="@string/app_name" > </activity> |
基本的にはこれだけです。
サンプルコード
まとめてみます。その前にSubActivityとして別のJavaファイルを作らないといけません。
一番左の階層から「app」「java」「xxx.xxx.xxx」を選択して
「New」「Java Class」から新しいClass ファイルを作ります。
MainActivityと同じレベルにSubActivityができればOKです。
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 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.content.Intent; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button sendButton = findViewById(R.id.send_button); // sendButton.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // Intent intent = new Intent(getApplication(), SubActivity.class); // startActivity(intent); // } // }); // lambda式 sendButton.setOnClickListener(v -> { Intent intent = new Intent(getApplication(), SubActivity.class); startActivity(intent); }); } } |
レイアウトですが、わかりやすくするために背景色を入れたり文字を大きくしたりしました。確認するだけなら文字列だけでも大丈夫です。
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 |
<?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" android:background="#dfe" tools:context=".MainActivity"> <TextView android:text="@string/main" android:textSize="30sp" android:layout_margin="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" 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.3"/> <Button android:id="@+id/send_button" android:text="@string/move" android:textSize="30sp" android:layout_margin="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
追加した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 |
//package your.package.name import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class SubActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub); Button returnButton = findViewById(R.id.return_button); // returnButton.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // finish(); // } // }); // lambda式 returnButton.setOnClickListener(v -> finish()); } } |
SubActivityで読んでいるレイアウトファイルも作成する必要がありますが、
「New」「XML」「Layout XML File」から作れます。あるいはFileからでも可能です。
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 |
<?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" android:background="#fee" tools:context=".MainActivity"> <TextView android:text="@string/sub" android:textSize="30sp" android:layout_margin="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" 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.3"/> <Button android:id="@+id/return_button" android:text="@string/return_sub" android:textSize="30sp" android:layout_margin="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
リソースファイルです。retrunというキーワードは予約語なので使えないですね
strings.xml
1 2 3 4 5 6 7 |
<resources> <string name="app_name">Your App Name</string> <string name="main">Main Activity</string> <string name="move">MOVE</string> <string name="sub">Sub Activity</string> <string name="return_sub">RETURN</string> </resources> |
マニフェストです
AndroidManifest.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 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name" <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SubActivity" android:label="@string/app_name" > </activity> </application> </manifest> |
戻りは、ユーザーのリターンキーをタップしても戻れます
同一Activityでの画面変更
実はScreenの画面を変えたいだけの場合はわざわざActivityを使わなくてもできます。
特にテキスト内容や画像を変えるだけのようなケースではこのほうが軽くなります。
Activityでの画面遷移と同じことができるようにしてみます。
activity_main.xml
activity_sub.xml
のレイアウトファイルはそのまま使います。簡単に言えば、MainActivityからこのレイアウトファイルを呼び出せばいいだけです。
デフォルトで設定されている setContentView(…) ですがこれがレイアウトファイルを呼び出しているところです。
1 |
setContentView(R.layout.activity_main); |
これを使って2つのレイアウトファイルを呼んでいきます。
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 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setScreenMain(); } private void setScreenMain(){ setContentView(R.layout.activity_main); Button sendButton = findViewById(R.id.send_button); // sendButton.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // setScreenSub(); // } // }); // lambda式 sendButton.setOnClickListener(v -> setScreenSub()); } private void setScreenSub(){ setContentView(R.layout.activity_sub); Button returnButton = findViewById(R.id.return_button); // returnButton.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // setScreenMain(); // } // }); // lambda式 returnButton.setOnClickListener(v -> setScreenMain()); } } |
setScreenMain()とsetScreenSub()を作ってそれぞれのレイアウトファイルを呼び出しています。この程度の画面であればActivityの画面遷移よりもサクサク動作するのが分かります。画面ごとの機能が異なり複雑にならなければ使い道はありそうです。
尚、Kotlinではこのようになります。
関連ページ:
References:
アクティビティ | Android Developers
一般的なインテント | Android Developers