AndroidのUIを作るうえで基本となる内容をまとめたいと思います。
レイアウト概要、レイアウト単位、LinearLayout、RelativeLayoutの四回にわたってレイアウトの基本について記事を書きました。
今回からはそのレイアウトの中でユーザからの入力を受け付けるコンポーネントについて説明していきます。
本稿では、最も基本的な入力コントロールコンポーネントである”ボタン”を扱います。
Button
“ボタン”とはユーザーがタッチしたとき何かしらのアクションを行うためのUIコンポーネントです。
“ボタン”を表示するにはandroid.widgetパッケージのButtonクラスを用います。
まずは、ActivityのレイアウトファイルにButtonを配置しましょう。
activity_main.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:padding="16dp" tools:context="jp.techpjin.buttonsample.MainActivity" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button_1" android:id="@+id/button1"/> </LinearLayout>
ButtonはTextViewのサブクラスなのでandroid:text属性が有効です。
表示したい文字はandroid:textに設定しましょう。
文字ではなくアイコンを表示したい場合はImageViewのサブクラスであるImageButtonを用います。android:srcに表示したい画像を指定します。
下の例では/res/drawableにpen_image.pngファイルを置き、それを読み込んでいます。
activity_main.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:padding="16dp" tools:context="jp.techpjin.buttonsample.MainActivity" android:orientation="vertical"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/pen_image" android:text="Button2" android:id="@+id/button2"/> </LinearLayout>
文字とアイコンを同時に使いたい場合は、Buttonのandroid:drawableLeft属性を用います。
android:textに文字を、android:drawableLeftにImageButtonのandroid:srcと同じ要領で画像を指定します。
activity_main.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:padding="16dp" tools:context="jp.techpjin.buttonsample.MainActivity" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button3" android:drawableLeft="@drawable/pen_image" android:id="@+id/button3"/> </LinearLayout>
ここまでで3通りのボタンを表示することは出来ましたが、押されたときの反応がなければボタンとはいえないですね。
次でボタンが押された(クリック)の処理の設定仕方についておさえましょう。
クリックイベント
ユーザがボタンを押したときの処理を定義するには大きく分けて二通りあります。
onClick属性を用いる
一つ目が、xmlレイアウトファイル内でButtonにandroid:onClick属性を指定する方法です。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button_1" android:id="@+id/button1" android:onClick="sendMessage"/>
上記のようにandroid:onClickにボタンが押されたときに呼ばれるメソッド名を記します。
そしてこのButtonをレイアウト内にもつActivityにこの名前のメソッドを実装します。
public void sendMessage(View view){ //ボタンが押されたときの処理 Toast.makeText(this,"onClick属性を指定",Toast.LENGTH_SHORT).show(); }
メソッド名は適宜任意のものでかまいませんが、・publicであること・返り値がvoidであること・引数
はひとつのViewのみであること、の三点を満たしているメソッドでなければなりません。
OnClickListenerを用いる
二つ目の方法が、直接View.OnClickListenerインターフェースを実装する方法です。
(*ActivityではなくFragmentのレイアウトにButtonをもつ場合はonClick属性を用いるは適切でありません。
基本的には以下で説明する方法を用いる・目にする機会のほうが遥かに多いと思います。)
Viewクラスには、onClickメソッドが定義されたView.OnClickListenerインターフェースがあります。
このViewがクリックされたときonClickが呼ばれるので、onClickの中身を実装してあげればクリックされたときの処理を定義できることになります。
リスナーの登録はsetOnClickListener(View.OnClickListener)を用います。
MainActivity
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button)findViewById(R.id.button1); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //ボタンが押されたときの処理 Toast.makeText(getApplicationContext(),"匿名クラスとして実装",Toast.LENGTH_SHORT).show(); } }); } }
上記ではView.OnClickListenerインターフェース無名内部クラスとして実装しています。
また似たような方法としてActivity自身でインターフェースを実装してしまうという手もあります。
public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = (Button)findViewById(R.id.button1); button1.setOnClickListener(this); } @Override public void onClick(View v) { Toast.makeText(getApplicationContext(),"Activityでインターフェース実装",Toast.LENGTH_SHORT).show(); } }
この場合はActivityでonClickを定義し、setOnClickListenerの引数にはMainActivityのインスタンス自身すなわちthisを与えます。
なお、レイアウト内に複数のボタンがある場合は、このようにActivityで実装する方法は注意が必要です。
各ボタンがおされたとき当然ですが同じonClickが呼ばれるのでonClick内でどのButtonのクリックにより
呼ばれたのかを判別し処理を分岐させる必要があります。
判別は以下のようにgetIdでリソースIDを取得し比較することで行えます。
public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = (Button) findViewById(R.id.button1); Button button2 = (Button) findViewById(R.id.button2); button1.setOnClickListener(this); button2.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.button1) { Toast.makeText(getApplicationContext(), "Button1が押されました", Toast.LENGTH_SHORT).show(); } else if (v.getId() == R.id.button2) { Toast.makeText(getApplicationContext(), "Button2が押されました", Toast.LENGTH_SHORT).show(); } } }
以上がButtonがクリックされたときの処理の定義方法になります。
インターフェースの概念や無名内部クラスの扱いは初心者には少々難解かも知れませんが、
まずはButtonに対応した処理を書くにはsetOnClickListener(View.OnClickListener)を呼ぶと覚えておきましょう。
ちなみにこれらの実装方法の中で筆者は直接無名内部クラスを渡す方法が好みです。参照先がわかりやすいので。
Androidのボタンの基本的な実装方法は以上です。