レッスン1:Building Your First App(3)
しばらく、このままトレーニングをなぞっていきたいと思います。
前回までのレッスンで、テキスト入力エリアとボタンの表示されたひとつの画面(activity)が出来上がりました。今回のレッスンでは、このボタンがクリックされた時に、別のactivityがスタートするコードを最初に作成された「MyActivity.java」に記述していきます。
別の Activity を開始する | Android Developers
Sendボタンクリック時の反応
- 前回のレッスンでボタンを配置したレイアウトファイル(res/layout/activity_my.xml)を開きます
- Button要素に android:onClick属性を追加して、「sendMessage」という値を設定します。この値は、ユーザーがボタンをクリックした時に、activityの中からシステムが呼び出すメソッド名です。
res/layout/activity_my.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage"/>
</LinearLayout>
- java/jp.co.monoworks.myfirstappディレクトリの実行ファイル(MyActivity.java)を開きます。※「jp.co.monoworks」の部分は各自の登録ドメイン名によって異なります
- MyActivityクラスに sendMessage()メソッドを追加。
java/jp.co.monoworks.myfirstapp/MyActivity.java
package jp.co.monoworks.myfirstapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MyActivity extends AppCompatActivity {
/** ユーザーがSendボタンをクリックした時に呼ばれます */
public void sendMessage(View view){
// ボタンを押した時にどういった対応をするか、ここに記述
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
}
@Override
<中略>
}
android:onClick属性に与えられたメソッド名「sendMessage」と実行ファイルの sendMessage()メソッドを関連付けるため、sendMessage()メソッドは、次の規則に従って署名します
- publicであること
- 戻り値がvoidであること
- パラメータには必ず Viewを設定すること
なお、Android Studioで sendMessage()メソッドに Viewパラメータを記述すると、importするように促されるので、実行ファイル(MyActivity.java)の先頭付近(importの並び)にimportの記述を追加します(Android Studioの場合、Alt+Enterで自動的にimportの記述を追加してくれます)
続いて、sendMessage()メソッドの中に、テキストフィールドに入力された内容を読み取って、別のactivityにその内容を渡すための記述をおこなっていきます。
Intentを構築
-
実行ファイル(MyActivity.java)内の sendMessage()メソッドに「DisplayMessageActivity」というactivityをスタートさせるためのIntentを作成。(DisplayMessageActivityは後で作成するので、この段階ではAndroid Studioに「参照先がないよ」と怒られますが、気にせず進めます)
/** ユーザーがSendボタンをクリックした時に呼ばれます */ public void sendMessage(View view){ // ボタンを押した時にどういった対応をするか、ここに記述 Intent intent = new Intent(this, DisplayMessageActivity.class); }
このコンストラクタには2つのパラメータが指定されています。
-
最初のパラメータは Contextです(Activityクラスは Contextのサブクラスであるので「this」が使われています)
-
2つ目のパラメータには、Intentの配信先(この例では次に起動するactivity)となるコンポーネントのクラスを指定します
-
Intentの記述をしていると、Viewパラメータの時と同じく importするように促されるので、importの記述を追加
import android.content.Intent;
-
sendMessage()メソッド内に、EditText要素を getするため findViewById()を記述します
/** ユーザーがSendボタンをクリックした時に呼ばれます */ public void sendMessage(View view){ // ボタンを押した時にどういった対応をするか、ここに記述 Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); }
-
EditTextクラスのimport宣言を実行ファイル(MyActivity.java)の先頭付近に追加(Android Studioの場合、Alt+Enter)
-
getした文字列をそのまま文字列として「message」というローカル変数に割り当てて、Intentにその変数を追加する putExtra()メソッドを記述。putExtra()メソッドは、最初のパラメータにキーの名前(EXTRA_MESSAGE)を、二番目のパラメータに値(ローカル変数「message」)を格納して、Intentがデータの受け渡しできるよう準備します。このキーとデータのペアを「extras」と呼びます
/** ユーザーがSendボタンをクリックした時に呼ばれます */ public void sendMessage(View view){ // ボタンを押した時にどういった対応をするか、ここに記述 Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); }
-
先ほど記述したキー(EXTRA_MESSAGE)は未定義なので、MyActivityクラスの先頭にキー定義を追加します。intentのキーを定義する場合、他のアプリとデータの受け渡しが発生した場合でも同じキー名にならないように、一般的にパッケージ名を付加することで、一意性を保証します。また、受け渡し先のactivityから受け渡すデータを参照できるように、アクセス修飾子は publicにしておきます
public class MyActivity extends AppCompatActivity { public final static String EXTRA_MESSAGE = "jp.co.monoworks.myfastapp.MESSAGE" … }
-
sendMessage()メソッド内に startActivity()メソッドを呼び出して、そこにステップ1で作成したIntentオブジェクトを渡すと、一連のintentが終了します。
/** ユーザーがSendボタンをクリックした時に呼ばれます */ public void sendMessage(View view){ // ボタンを押した時にどういった対応をするか、ここに記述 Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); startActivity(intent); }
システムがこの呼出を受け取り、Intentによって指定されたActivityのインスタンス(実データ)を起動します。
最終的な実行ファイル(MyActivity.java)の記述
java/jp.co.monoworks.myfirstapp/MyActivity.java
package jp.co.monoworks.myfirstapp;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
public class MyActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "jp.co.monoworks.myfastapp.MESSAGE";
/** ユーザーがSendボタンをクリックした時に呼ばれます */
public void sendMessage(View view){
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
}
@Override
<中略>
}
MyActivityからのIntentを引き継ぐActivity(DisplayMessageActivity)の作成
Activityの全サブクラスは、onCreate()メソッドを実装しなければいけません。このメソッドは、そのactivityがメッセージを持ったintentを受け取り、そのメッセージを表示する場所です。また、onCreate()メソッドは、activityコンポーネントの初期設定をおこなう場所であり、setContentView()でレイアウトの定義もおこないます。
Android Studioの機能を使った新しいActivityの作成
- Android Studioのjavaディレクトリからパッケージ(jp.co.monoworks.myfastapp)を選択して右クリックから [New] > [Activity] > [Blank Activity]を選択
-
Activityのカスタマイズ画面が表示されるので、activity関連の項目に下記の値を設定して「Finish」をクリック
- Activity Name:DisplayMessageActivity
- Layout Name:activity_display_message
- Title:My Message
- Hierarchical Parent:jp.co.monoworks.myfastapp.MyActivity
- Package name:jp.co.monoworks.myfastapp(各自のパッケージ名)
-
上記手順で作成した DisplayMessageActivity.javaファイルを開くと、そこには必須項目である onCreate()メソッドと appバー上での動きを制御する onOptionsItemSelected()メソッドが実装されています。後ほど onCreate()メソッドは更新します
-
今回のレッスンでは不要な onCreateOptionsMenu()メソッド部分の記述を削除します
Android Studioで本レッスンのアプリを作成している場合、この段階でアプリを実行できます。ただし、Sendボタンを押して、次のactivityを起動しても、その画面には「最初のactivityでテキスト入力欄に入力した文字列」ではなく「テンプレートとして提供されているデフォルトの文字列(Hello world)」が表示されます。
手動で(Android Studioの機能を使わずに)新規Activityを作成
本家サイトでは、Android Studio以外のIDE(統合開発環境)を使っていたり、コマンドラインツールで新規Activityを作成する場合、手動で DisplayMessageActivity.javaファイルを作成して、中身を記述したり、文字列ファイル(strings.xml)とマニフェストファイル(AndroidManifest.xml)に手を加える方法について解説していますが、ここでは割愛します。
Intent(とそこに含まれるメッセージ)を受け取る
ナビゲートの方法に関係なく、すべての Activityは Intentによって呼び出すことができます。getIntent()メソッドを呼び出すことで activityを起動した Intentを取得して、そこに含まれるデータを取り出すことができます。
-
java/jp.co.monoworks.myfastapp(各自のパッケージ名)ディレクトリ内のDisplayMessageActivity.javaファイルを開く
-
onCreate()メソッド内の下記行を削除
setContentView(R.layout.activity_display_message);
-
削除した場所に下記行を追加(intentを取得して、ローカル変数に割り当て)
Intent intent = getIntent();
-
Intentクラスをimportに追加(Alt+Enter)
-
さらに下記行を追加(getStringExtra()メソッドを使って、MyActivityから配信されたメッセージを抽出)
String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
受け取ったメッセージを表示
-
先ほど追加した行に続けて下記を追記(onCreate()メソッド内に TextViewオブジェクトを作成)
TextView textView = new TextView(this);
-
さらに次の2行を追加(表示するテキストの内容(message)とサイズ(40)を設定)
textView.setTextSize(40); textView.setText(message);
-
さらに次の行を追加(setContentVIew()に textViewを渡して activityのレイアウトにTextViewビューを設定)
setContentView(textView);
-
TextViewクラスをimportに追加(Alt+Enter)
最終的にこんな感じの記述になります。
java/jp.co.monoworks.myfastapp/DisplayMessageActivity.java
package jp.co.monoworks.myfirstapp;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.TextView;
public class DisplayMessageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);</br> // intentからメッセージを取得
Intent intent = getIntent();
String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);</br> // text viewを作成
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);</br> // activityのレイアウトとして text viewを設定
setContentView(textView);
}
/* onCreateOptionsMenu()メソッドは削除しています */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The actkakiion bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();</br> //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}</br> return super.onOptionsItemSelected(item);
}
}
ここまでのトレーニングで作成したアプリを実行すると、こんな感じになります。
- アプリ起動画面(最初のactivity)
- テキスト入力欄に「表示させるメッセージ」を入力して「Sned」ボタンを押すと
- 次の画面(二番目のactivity)が起動して「受け取ったメッセージ」が表示されます
以上で「Building Your First App」トレーニングが終了です。
【参考サイト】
コメント
コメントなどありましたら、GitHubのディスカッションへお願いします。(書き込みには、GitHubのアカウントが必要です)