Tips

Android ユーザーインターフェースの基礎 【Android TIPS】

 

レイアウトXMLファイルに限らず文字列リソースファイル等のリソースファイルは「res」フォルダ以下に配置します。これらのファイルは保存(アプリの実行時ではありません!)すると、ADTによって自動的にコンパイルされ、genディレクトリ以下にJavaファイル「R.java」を作成します。
Androidアプリが実行される際にはアプリケーションに必要なファイルは全てAPKという形でパッケージングされますが、この中にはXMLファイルから自動生成された「R.java」も含まれます。(正確には「R.java」をコンパイルしたクラスファイルです。)
つまり、コンパイル時に静的に決定している情報のみがXMLファイルで定義することができることになります。これは、Javaプログラムでリソースファイルを修正するということは不可能ということを意味します。
実行時にレイアウトを動的に変更したい場合などは、2つ目の方法であるJavaプログラムによる定義方法を使うしかないということになります。

 

ただし、一般的にJavaプログラムで1からレイアウトを作成するということはしないと言っていいでしょう。これはレイアウトXMLファイルを使う場合に比べ圧倒的にメンテナンス性が落ちてしまったり、コード量が増えるためです。

 

では、動的にレイアウトを変更したい場合はどうするのでしょうか?
一般的には、変更する箇所をレイアウトXMLファイルとして部品化し、Javaプログラムからはこの部品化したレイアウトXMLファイルを読み込むという方法がとられるようです。

XMLファイルでユーザーインターフェースを定義する
まずは、XMLファイルによるレイアウト定義方法を見ていきましょう。

 

ここで、当たり前のことから確認しておきます。
AndroidアプリはJavaプログラムで作成します。これは、画面上のアイコンを指でクリックするとJavaプログラムがそれを検知し、アイコンのアプリケーションを起動しているということです。
起動命令を受けたAndroidアプリは、画面の初期化を始めます。この際に、画面レイアウトの元になるレイアウトXMLファイルが必要になるわけです。

 

XMLファイルによるレイアウト定義のポイントは、レイアウトXMLファイルとJavaプログラムとの関連付けにあります。
この関連付けにはActivityクラスに定義されているsetContentView()メソッドを用います。
※Activityについては別途詳しく紹介しますが、ここでは画面を表す単位(クラス)と思ってください。

 

では、setContentView()メソッドのシグネチャを確認しましょう。

public void setContentView (int layoutResID)

メソッドの引数にはintを指定します。これにリソースIDを利用することで、レイアウトXMLファイルとActivityの紐づけを行うことができるのです。

 

HelloWorldプログラムでは、画面クラスMainActivity.javaそのレイアウトXMLファイルactivity_main.xmlがあります。この二つのファイルでHelloWorldと表示する画面を作っている(正確にはstrings.xmlも含みます)わけですが、この二つのファイルを結び付けているのは双方についている「main」というワードではありません。
最近流行りの「Ruby on Rails」などでは「設定より規約」という基本理念を元に、クラス名やファイル名などから自動的に関連付けを行っているのですが、Androidではこのような方法を取っていません。かならずJavaプログラム上で関連付けを行うためのメソッドを実行する必要があります。

 

では、使用例です。実際にHelloWorldプログラムで行われている処理になります。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

6行目の「setContentView(R.layout.activity_main);」が「MainActivity.java」と「activity_main.xml」を紐づけている処理になります。

Javaプログラムでユーザーインターフェースを定義する
つぎに、Javaプログラムによるレイアウト定義方法です。

 

先ほど紹介したsetContentView()メソッドには他にも次のようなシグネチャのメソッドが用意されています。

public void setContentView (View view)
public void setContentView (View view, ViewGroup.LayoutParams params)

どちらも第1引数にViewクラスのオブジェクトを渡しています。
ユーザーインターフェイスは必ずツリー構造になりますので、そのルート(ツリーの根っ子のViewオブジェクト)をこの第1引数に指定します。

 

では、使用例です。

TextView textView = new TextView(this);
setContentView(textView);

この例では、TextViewクラス(Viewクラスのサブクラス)をインスタンス化し、Activityと紐づけを行っています。TextViewがひとつだけある画面ということですね。ただし、このように使用されることはほとんどなく、一般的にはViewGroupオブジェクト(Viewのサブクラス)が指定されることになるでしょう。

レイアウトXMLファイルとJavaプログラムによる定義方法の違い
同じ画面レイアウトをそれぞれのレイアウト定義方法を使い、コーディングしてみましょう。

 

まずは、レイアウトXMLファイルを使った方法です。
「res/layout/activity_main.xml」ファイル

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ボタンを押して下さい"/>
    <Button
        android:id="@+id/buttton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ボタン"/>
</LinearLayout>
 

「src/com.example.helloworld/MainActivity.java」ファイル

package com.example.helloworld;
// ・・・中略・・・
public class MainActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
// ・・・中略・・・

}

レイアウトXMLファイル上でツリー構造を作り、そのファイルとMainActivity.javaを「setContentView(R.layout.activity_main);」で紐付けしています。

 

次に、Javaプログラムでレイアウトを定義する方法です。
「src/com.example.helloworld/MainActivity.java」ファイル

package com.example.helloworld;
// ・・・中略・・・
public class MainActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        TextView textView = new TextView(this);
        textView.setText("ボタンを押して下さい");
 
        Button button = new Button(this);
        button.setText("ボタン");
 
        LinearLayout layout = new LinearLayout(this);
        layout.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        layout.addView(button, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        setContentView(layout);
    }
 
// ・・・中略・・・

}

※レイアウトXMLファイルは不要です。

 

8行目でTextViewオブジェクトを作成、おなじく11行目でButtonオブジェクトを作成しています。これらのオブジェクトはLinearLayoutの子供になります。
次に14行目でルートのLinearLayoutオブジェクトを作成し、15から16行目でその子供として上記TextViewおよびButtonオブジェクトを設定しました。このときレイアウトに関する設定をLayoutParamsオブジェクトとして第2引数に渡しています。レイアウトXMLファイルのTextViewタグやButtonタグの属性「android:layout_width」「android:layout_height」に該当します。
あとは、LinearLayoutオブジェクトをMainActivityクラスと紐付ける処理を18行目で行っています。

Androidアプリ開発の必須知識!JAVAプログラミングを学べる連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search