Mono Works

チラシのすきま

Android開発者トレーニング(Lesson1)Activityから別のActivityへ

レッスン1:Building Your First App(3)

しばらく、このままトレーニングをなぞっていきたいと思います。

androiddevmemo20151020_00

前回までのレッスンで、テキスト入力エリアとボタンの表示されたひとつの画面(activity)が出来上がりました。今回のレッスンでは、このボタンがクリックされた時に、別のactivityがスタートするコードを最初に作成された「MyActivity.java」に記述していきます。

別の Activity を開始する  |  Android Developers

Sendボタンクリック時の反応

  1. 前回のレッスンでボタンを配置したレイアウトファイル(res/layout/activity_my.xml)を開きます
  2. 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>
  1. java/jp.co.monoworks.myfirstappディレクトリの実行ファイル(MyActivity.java)を開きます。※「jp.co.monoworks」の部分は各自の登録ドメイン名によって異なります
  2. 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()メソッドは、次の規則に従って署名します

  1. publicであること
  2. 戻り値がvoidであること
  3. パラメータには必ず Viewを設定すること

なお、Android Studioで sendMessage()メソッドに Viewパラメータを記述すると、importするように促されるので、実行ファイル(MyActivity.java)の先頭付近(importの並び)にimportの記述を追加します(Android Studioの場合、Alt+Enterで自動的にimportの記述を追加してくれます)

続いて、sendMessage()メソッドの中に、テキストフィールドに入力された内容を読み取って、別のactivityにその内容を渡すための記述をおこなっていきます。

Intentを構築

  1. 実行ファイル(MyActivity.java)内の sendMessage()メソッドに「DisplayMessageActivity」というactivityをスタートさせるためのIntentを作成。(DisplayMessageActivityは後で作成するので、この段階ではAndroid Studioに「参照先がないよ」と怒られますが、気にせず進めます)

    /** ユーザーがSendボタンをクリックした時に呼ばれます */
    public void sendMessage(View view){
        // ボタンを押した時にどういった対応をするか、ここに記述
        Intent intent = new Intent(this, DisplayMessageActivity.class);
    }
    

    このコンストラクタには2つのパラメータが指定されています。

  2. 最初のパラメータは Contextです(Activityクラスは Contextのサブクラスであるので「this」が使われています)

  3. 2つ目のパラメータには、Intentの配信先(この例では次に起動するactivity)となるコンポーネントのクラスを指定します

  4. Intentの記述をしていると、Viewパラメータの時と同じく importするように促されるので、importの記述を追加

    import android.content.Intent;
    
  5. 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);
    }
    
  6. EditTextクラスのimport宣言を実行ファイル(MyActivity.java)の先頭付近に追加(Android Studioの場合、Alt+Enter)

  7. 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);
    }
    
  8. 先ほど記述したキー(EXTRA_MESSAGE)は未定義なので、MyActivityクラスの先頭にキー定義を追加します。intentのキーを定義する場合、他のアプリとデータの受け渡しが発生した場合でも同じキー名にならないように、一般的にパッケージ名を付加することで、一意性を保証します。また、受け渡し先のactivityから受け渡すデータを参照できるように、アクセス修飾子は publicにしておきます

    public class MyActivity extends AppCompatActivity {
        public final static String EXTRA_MESSAGE = "jp.co.monoworks.myfastapp.MESSAGE"
    
        
    }
    
  9. 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の作成

  1. Android Studioのjavaディレクトリからパッケージ(jp.co.monoworks.myfastapp)を選択して右クリックから [New] > [Activity] > [Blank Activity]を選択
androiddevmemo20151031_1
  1. 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(各自のパッケージ名)
  2. 上記手順で作成した DisplayMessageActivity.javaファイルを開くと、そこには必須項目である onCreate()メソッドと appバー上での動きを制御する onOptionsItemSelected()メソッドが実装されています。後ほど onCreate()メソッドは更新します

  3. 今回のレッスンでは不要な 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を取得して、そこに含まれるデータを取り出すことができます。

  1. java/jp.co.monoworks.myfastapp(各自のパッケージ名)ディレクトリ内のDisplayMessageActivity.javaファイルを開く

  2. onCreate()メソッド内の下記行を削除

    setContentView(R.layout.activity_display_message);
    
  3. 削除した場所に下記行を追加(intentを取得して、ローカル変数に割り当て)

    Intent intent = getIntent();
    
  4. Intentクラスをimportに追加(Alt+Enter)

  5. さらに下記行を追加(getStringExtra()メソッドを使って、MyActivityから配信されたメッセージを抽出)

    String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
    

受け取ったメッセージを表示

  1. 先ほど追加した行に続けて下記を追記(onCreate()メソッド内に TextViewオブジェクトを作成)

    TextView textView = new TextView(this);
    
  2. さらに次の2行を追加(表示するテキストの内容(message)とサイズ(40)を設定)

    textView.setTextSize(40);
    textView.setText(message);
    
  3. さらに次の行を追加(setContentVIew()に textViewを渡して activityのレイアウトにTextViewビューを設定)

    setContentView(textView);
    
  4. 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);
    }
}

ここまでのトレーニングで作成したアプリを実行すると、こんな感じになります。

  1. アプリ起動画面(最初のactivity)
androiddevmemo20151031_2
  1. テキスト入力欄に「表示させるメッセージ」を入力して「Sned」ボタンを押すと
androiddevmemo20151031_3
  1. 次の画面(二番目のactivity)が起動して「受け取ったメッセージ」が表示されます
androiddevmemo20151031_4

以上で「Building Your First App」トレーニングが終了です。

【参考サイト】

Starting Another Activity | Android Developers

コメント

コメントなどありましたら、GitHubのディスカッションへお願いします。(書き込みには、GitHubのアカウントが必要です)
執筆者
"ぽぽろんち" @pporoch
pporoch120
Mono Worksの中の人。好きなことをつらつらと書き留めてます。
ギターを始めてから 練習動画をYouTubeにアップしてます。ご笑納ください。
"DQX@ぬここ(UD487-754)、コツメ(NO078-818)"
採用案内