レイアウトをプログラムから操作
さて続いては、定義されたレイアウトを表示させ制御します。srcフォルダから自動生成されたメインアクティビティのファイルを開きます(今回は、プロジェクトの作成時にMyMainという名前を付けています)。
すでに、main.xmlを読んで表示する機能はできています。そこで、ボタンを押したときにEditTextの内容を使って、1番上のTextViewを書き換えることにします。
その前に準備として、文字列リソースであるhelloを書き換えます。現時点でhelloは「Hello World, MyMain!」となっていますので、これを「Hello World, 」とします。
では、プログラムの修正に入りましょう。現在のソースコードは、下のリスト2のようにになっているはずです。
リスト2
package com.tyrell_replicants.sample04;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MyMain extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
まずは、xmlで定義したオブジェクトをプログラムから扱うために、オブジェクトを参照する変数を作ります。たとえば、画面先頭のTextView(@+id/Messageを指定したもの)を参照するには、まず、「public class MyMain extended Activity {」の次の行に以下のコードを挿入します。
private TextView message;
そして「setContentView(R.layout.main);」の次の行に以下のコードを挿入します。
message = (TextView)this.findViewById(R.id.Message);
このコードは、TextViewを参照するmessage変数を定義し、その中身としてthis.findViewByIdメソッドの結果を代入するものです。findViewByIdは、さまざまなビューへの参照を返すため、Viewクラスを返すメソッドになっているので、TextViewクラスのオブジェクトを参照するmessageに代入するにはキャストしなければなりません。
「findViewById」というメソッドは、引数として指定されたidからビューを探すメソッドです。thisは自分自身、この場合には、MyMainクラスになります。つまり、findViewByIdは、Activityクラスで定義されているメソッドです。
さてこの引数には「R.id.Message」が指定されています。“R”はこのアプリケーション自身のリソースをまとめてオブジェクトで、“id”はその中のidの定義になります。つまり、これはリソースとして定義されている“Message”という名前のidを表します。これは、xmlのid定義である「@+id/Message」と対応します。xmlファイルで「@+id/X」という型式で定義されたidはプログラムからは、「R.id.X」で参照できます。
同様に、InputTextやSetButtonも参照できるようにしましょう(リスト3)。
リスト3
package com.tyrell_replicants.sample04;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MyMain extends Activity {
private TextView message;
private EditText inputText;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
message = (TextView)this.findViewById(R.id.Message);
inputText=(EditText)this.findViewById(R.id.InputText);
Button setButton=(Button)this.findViewById(R.id.SetButton);
}
}
コードを入力するときにエラー表示が出るので、TextViewなどのインポートも定義します。さて、ボタンの処理を記述することにしましょう。onCreateの次に以下のメソッドを定義します。
public void SetButtonOnClick(View v){
message.setText(this.getString(R.string.hello)+inputText.getText());
}
とします。ここで行なっているのは、文字列リソースhelloとinputTextに入力されたテキストをつないで、Messageのテキストとして設定しているだけです。messageにテキストを設定するのには「setText」メソッドを使い、inputTextに入力されたテキストを取得するには「getText()」メソッドを使っています。文字列リソースの参照は、このように自分自身が持つgetStringメソッドを「R.string.hello」を引数にして呼び出すだけです。
ですが、このままでは、ボタンとこのSetButtonOnClickの対応が付いていません。この対応を付けるにはいくつか方法がありますが、XMLでレイアウトを使っている場合には、ボタンの「On click」プロパティに直接、このメソッド名を書く方法が簡単です。
エディターにある「main.xml」タブをクリックしてレイアウトエディターに戻り、SetButtonのプロパティで「On Click」を探し、値として呼び出したいメソッド名である「SetButtonOnClick」を指定します。
ボタンの処理を書くほかの方法としては、ボタンを表すsetButtonに対して、EventListenerを定義する方法や、MyMainクラス自体をEventListenerにして、onClickメソッドを定義する方法があります。まず、EventListenerを定義する方法では、
:
Button setButton=(Button)this.findViewById(R.id.SetButton);
setButton.setOnClickListener(new OnClickListener(){
@Overrride
public void onClick(View v){
/** ボタンを押したときの処理 **/
}
});
:
というような感じでボタンの動作を定義します。ここに出てくるOnClickListenerがEventListenerと呼ばれるもので、イベントの発生時に呼び出されるオブジェクトです。ビューに対して、このオブジェクトを「setOnClickListener」で指定することで、イベント(ユーザーによるビューへのタッチ)で、このオブジェクトのonClickメソッドが呼び出されるのです。
このように記述がちょっと面倒ですが、何をしているのかがその場でわかるというメリットもあります。筆者は記述が面倒なので、あまり好きではありませんが、今回のように1行だけで済む処理ならば、ボタンの定義のそばに動作を記述でき、関連するコードを一ヵ所にまとめておけるというメリットがあります。逆にボタンを押したときの処理が大きくなってしまうとプログラムがわかりにくくなる可能性もあります。
もう1つは、MyMainの定義にOnClickListenerを加える方法です。
public class MyMain extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
:
Button setButton=(Button)this.findViewById(R.id.SetButton);
:
}
public void onClick(View v){
if ( v == setButton) {
/** ボタンを押したときの処理 **/
}
}
この方法では、MyMainは、アクティビティクラスであると同時にOnClickListenerのインターフェースも引き継いでいます。このため、Activityが扱うビューのすべてのonClickイベントがonClickメソッドを呼び出します。TextViewなどもClickイベントを発生します。なので、引数としてわたされるビューを使って、何がイベントを発生させたのかを判定する必要があります。半面、1つのアクティビティ上で発生したClickイベントをまとめて処理できるというメリットもあります。たとえば、複数のビューがあって、それらをユーザーがタッチしたとき、あるいは画面のどこをタッチしても同じ処理をしたいなどです。ただ、ビューとの関係がはっきりしない感じがあり、同じ処理をまとめて行なう、集中して管理したいといった理由がない限りは避けた方がいいでしょう。
では、実行してみましょう。エミュレーターでこのSample04を実行させると下のような画面が表示されるので、
テキスト入力欄を書き換えて、Setボタンを押します。すると、上部のメッセージが書き換えられました。
アイコンを変更する
最後に、アプリケーションのアイコンを変更する方法を解説します。まずはアイコン画像を作ります。アイコン画像はPNGファイルで、表示密度に合わせて3種類(72×72/48×48/32×32ドット)用意します。最初に72x72ドットのアイコンやそれ以上に大きな画像を作って、縮小していくと簡単です。
ファイルができたら、それぞれのPNGファイルを「res/drawable-hdpi」(72×72)、「res/drawable-mdpi」(48×48)、「res/drawable-ldpi」(32×32)というそれぞれのフォルダへ「icon.png」というファイル名でインポートして置き換えます。
アイコンを変更しておくと、エミュレーターで再度実行するときにラウンチャーなどから探すのがラクになります。また、Androidマーケットでアプリケーションを公開するときにも指定するようにしてください。
今回のプロジェクトの内容は以下のリンクをクリックすることでダウンロードできます。
またプログラムについてもAndroidマーケットで公開します。Android端末を持っているなら、Androidマーケットで「サンプルプログラム」をキーワードとして検索してみてください。
この連載の記事
-
第11回
スマホ
アプリケーションをAndroidマーケットに登録する -
第10回
スマホ
ブロードキャストへの応答とタイマ割り込み -
第9回
スマホ
Androidアプリで複数の項目を表示するリストビューを使う -
第8回
スマホ
Androidアプリに必要なダイアログを作る -
第7回
スマホ
Androidアプリの設定画面を作成する -
第6回
スマホ
Androidアプリ内で表示されるメニューを作成する -
第5回
スマホ
インテントによるアプリケーションとアクティビティの呼出し -
第3回
スマホ
アプリケーションの基本となる「アクティビティ」 -
第2回
スマホ
開発したアプリをエミュレーターやデバッガ上でテストする -
第1回
スマホ
Androidアプリの開発環境であるEclipseの使い方を知る - この連載の一覧へ