AndroidでGUI
Androidアプリケーションが起動されるとアプリケーションのメインとなるアクティビティが開始し、 Android システムによってそのアクティビティの onCreateメソッドが呼び出されます。
アクティビティクラスでGUI画面を表示するには、このonCreateイベントメソッドで画面の初期設定をおこなうコードを記述します。
コードによるGUI画面の作成
onCreateメソッドの中で、setContentViewメソッドを使ってcontentViewとなるViewクラスを継承したクラスのオブジェクトを設定します。
画面を構成するコンポーネント要素をウィジェットと呼んだりしますが、Viewクラスを継承したクラスはいわゆるウィジェットクラスです。
アンドロイド・プログラミングはじめのいっぽのHelloAndroidプロジェクトでのGUI画面のサンプルプログラムを再度、以下に示します。
package xxx.yyy; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloAndroid extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("ソースコードで表示文字列を変更する。"); setContentView(tv); } }
上記の例では、TextViewというテキストを表示するウィジェット(GUIコンポーネント)を1つ表示するだけのプログラムです。
TextViewクラスのオブジェクトを作成して(13行目)、 setTextメソッドでTextViewに表示させる文字列を設定(14行目)した後、それをアクティビティのコンテンツビューに指定(15行目)しています。
Viewクラスのコンストラクタの引数には通常、その親となるアクティビティクラスのオブジェクト(ここではthisを)指定します。
コンテンツビューに設定できるViewオブジェクトは1つだけです。
複数回、setContentViewメソッドを使用して複数のViewオブジェクトを設定した場合は、最後に指定したViewオブジェクトのみが有効になるようです。
複数のウィジェットを画面に表示させる場合には、コンテンツビューとなるViewオブジェクトにViewGroupクラスを継承したクラスのオブジェクトを指定します。
ViewGroupクラスはViewクラスのサブクラスです。
ViewGroupクラスはaddViewメソッドを使って、ViewGroupクラスの中にViewクラスを継承したクラスを複数配置する事ができます。
以下にコンテンツビューにViewGroupのオブジェクトを指定して複数のウィジェット(TextView,EditText,Button)を表示する例を示します。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ViewGroupクラスのサブクラスLinearLayoutのインスタンスを作成し、 // contentViewに設定。 LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); // TextViewオブジェクトを作成し、LinearLayoutオブジェクトに追加 TextView textView = new TextView(this); textView.setText("ラベルウィジェット"); layout.addView(textView); // EditTextオブジェクトを作成し、LinearLayoutオブジェクトに追加 EditText editText = new EditText(this); editText.setText("テキストボックスウィジェット"); layout.addView(editText); // Buttonオブジェクトを作成し、LinearLayoutオブジェクトに追加 Button button = new Button(this); button.setText("ボタンウィジェット"); layout.addView(button); }
ViewGroupクラスのサブクラスであるLinearLayoutクラスは、直訳すれば一直線にウィジェットを配置するレイアウトクラスという事になります。
7行目のsetOrientationメソッドで、ウィジェットを縦方向に配置するように指定しています。
このプログラムを実行すると、以下のような画面が表示されます。
ViewGroupクラスはウィジェットのコンテナクラスとなります。
ViewGroupクラスもViewクラスを継承したクラスなので、Viewクラスと 同等にあつかえますが、ViewGroupクラスは内部に複数のViewクラスを配置するための役割をする事になります。
ViewGroupクラスはViewクラスを配置する役割をになうので、レイアウト(クラス)と呼ばれる事もあるようです。
addViewメソッドを使って、ViewGroupのオブジェクトに更にViewGroupのオブジェクトを追加することで、 より複雑にウィジェットを配置する事ができます。
これによりViewオブジェクトを階層構造に配置する事ができ、setContentViewメソッドで指定したViewオブジェクト (コンテンツビュー)はアクティビティのルートViewオブジェクトという事になります。
xmlによるGUI画面の定義
xml設定ファイルを使ってGUI画面の定義をおこなう事もできます。
eclipseのパッケージ・エクスプローラーより、「/HelloAndroid/res/layout/main.xml」をダブルクリックして開いて下さい。
下図のような画面が表示されると思います。
この画面より、GUI操作により画面レイアウトの変更をおこなう事もできそうですが、 ここでは手っ取り早くxmlソースを直接編集する事にします。
図の下部に表示されているmain.xmlタブをクリックしてxmlソースを表示して、それを以下のように修正して下さい。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <EditText android:text="@string/edit_text" android:id="@+id/EditText01" android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText> <Button android:text="@string/button_text" android:id="@+id/Button01" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button> </LinearLayout>
同様に「/HelloAndroid/res/values/strings.xml」をダブルクリックして開いて strings.xmlタブをクリックしてxmlソースを以下のように修正して下さい。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Hello, Android</string> <string name="hello">ラベルウィジェット</string> <string name="edit_text">テキストボックスウィジェット</string> <string name="button_text">ボタンウィジェット</string> </resources>
次に、「/HelloAndroid/src/xxx/yyy/HelloAndroid.java」のソースのonCreateメソッドを以下のように修正します。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }
このプログラムを実行すると、前項の「コードによるGUI画面の作成」と同じ画面が表示されます。
GUI画面の作成は、「コードによるGUI画面の作成」と「xmlによるGUI画面の定義」のどちらでもおこなう事ができます。
「xmlによるGUI画面の定義」方法は、最近のはやりの,「コードとビュー(画面デザイン)の分離」を目的としています。
FlexやSilverlightなど新しいシステムでは、この方法がよくとられています。
今回はmain.xmlファイルをテキストで編集しましたが、「レイアウトタブ」を選択して「Android Layout Editor」で、 WYSIWYGで編集する事も可能なようです。
レイアウトについては「レイアウト(1)-ウィジェット(Viewクラス)の幅と高さと位置 - 愚鈍人」 も参照。
独自のViewクラスを使う
Viewクラスを継承した独自のViewクラスを定義して、表示させる事もできます。
まず、Viewクラスを継承した以下のようなクラスを新規に作成します。
package xxx.yyy; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.view.View; public class CustomView extends View { public CustomView(Context context) { super(context); setFocusable(true); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 通常はグラフィックを描画するコードをここに記述する。 canvas.drawColor(Color.BLUE); } }
上記のクラスは自分の描画領域をただ青く塗りつぶすだけのViewクラスです。
Viewクラスを継承したクラスは、グラフィックを描画する時によく使用されるパターンです。
具合的に、Viewクラスにグラフィックを描画する方法については、「グラフィックス(1)-Viewクラスへの描画」を参照して下さい。
アクティビティクラスのonCreateメソッドで、setContentViewメソッドの引数に 新しく作成したViewクラスのインスタンスを指定します。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new CustomView(this)); }
このプログラムを実行すると、以下のような画面が表示されます。
また、ViewGroupクラスを使用して、以下のように他のウィジェットとともに表示させる事もできる。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); Button button = new Button(this); button.setText("ボタンウィジェット"); layout.addView(button); layout.addView(new CustomView(this)); }
このプログラムを実行すると、以下のような画面が表示されます。