サンプル

3-2 ボタン(Button)とクリック・リスナー
ボタンにクリック・リスナーを付け、ボタンのクリック(タップ)で何かの処理を行う
方法を説明します。
1.
OnClickListener リスナーのインプリメント
「Button bt=(Button)findViewById(R.id.button);」で取得したボタン bt がクリックされ
たときの処理を行うクリック・リスナーを付けるにはまず、
「implements OnClickListener」
で OnClickListener インターフェースを Activity クラスに追加します。
public class Widget1 extends Activity implements OnClickListener{
こうしておいてから「bt.setOnClickListener(this);」でボタン bt にクリック・リスナー
を設定します。
2.
インターフェース
C++では複数のクラスを継承する多重継承を認めていますが、Java はこれを認めていま
せん。その代わりにインターフェースという概念により追加機能をクラスに実装できるよ
うにしました。インターフェースはクラスと同じようなものですが、データ部やコンスト
ラクタのない特別な小規模なクラスと考えることができます。インターフェースは
implements によりクラスに追加します。複数のインターフェースを追加したい場合はコン
マで区切ります。
3.
onClick メソッド
OnClickListener を追加した場合、そのクラス内に onClick メソッドが必要となります。
そしてこの onClick メソッド内にクリックが生じたときの処理内容を記述します。onClick
メソッドの引数 view にはクリックしたウイジェットの View クラスのオブジェクトが渡さ
れます。
public void onClick(View view) {
クリックが生じたときの処理
}
4.
タイトルバーへのテキストの表示
タイトルバーにテキストを表示するには setTitle メソッドを使って以下のようにします。
setTitle("テキスト");
「例題 3-2」ボタンをクリックしたらタイトルバーにテキストを表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="クリックしてね"
/>
</LinearLayout>
・MainActivity.java
package com.example.button1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt=(Button)findViewById(R.id.button);
bt.setOnClickListener(this);
}
public void onClick(View view) {
setTitle("クリックしました!");
}
}
5.複数のボタンの判定
複数のボタンに同じクリック・リスナーを設定した場合は、onClick メソッドの view 引
数を使って view.getId()でクリックされたボタンの ID を判定します。
public void onClick(View view) {
if (view.getId()==R.id.button1)
// ボタン 1 の処理
else if (view.getId()==R.id.button2)
// ボタン 2 の処理
}
「練習問題 3-2」
ボタンを 2 つ配置し、
クリックされたボタンをタイトルバーに表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ボタン1"
/>
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ボタン2"
/>
</LinearLayout>
・MainActivity.java
package com.example.button2;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
Button bt2=(Button)findViewById(R.id.button2);
bt2.setOnClickListener(this);
}
public void onClick(View view) {
if (
①
)
setTitle("ボタン1をクリック");
else if (
②
)
setTitle("ボタン2をクリック");
}
}
3-3 テキストビュー(TextView)
TextView はテキスト表示用のウィジェットで、<TextView>タグで定義します。
テキストビューにテキストを表示するには、setText メソッドを使います。
TextView text1=(TextView)findViewById(R.id.text1);
text1.setText("クリックしました");
テキストの表示色は setTextColor で設定できます。
text1.setTextColor(Color.GREEN);
「例題 3-3」ボタンをクリックしたら TextView にテキストを表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="クリックしてね"
/>
</LinearLayout>
・MainActivity.java
package com.example.textview1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt=(Button)findViewById(R.id.button1);
bt.setOnClickListener(this);
}
public void onClick(View view) {
TextView text1=(TextView)findViewById(R.id.text1);
text1.setText("クリックしました");
}
}
「練習問題 3-3」ボタン 1 をクリックしたら緑で、ボタン 2 をクリックしたら赤で TextView
にテキストを表示しなさい。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ボタン1"
/>
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ボタン2"
/>
</LinearLayout>
・MainActivity.java
package com.example.textview2;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
Button bt2=(Button)findViewById(R.id.button2);
bt2.setOnClickListener(this);
}
public void onClick(View view) {
TextView text1=(TextView)findViewById(R.id.text1);
if (view.getId()==R.id.button1){
text1.setTextColor(
①
);
text1.setText("ボタン1をクリック");
}
else if (view.getId()==R.id.button2){
text1.setTextColor(
②
);
text1.setText("ボタン2をクリック");
}
}
}
3-5 チェックボックス(CheckBox)
CheckBox は項目のクリックのたびにチェック状態(ON)と非チェック状態(OFF)を
交互に繰り返すウイジェットで<CheckBox >タグで定義します。チェックボックスは個々
に次のように取得します。
CheckBox cb=(CheckBox)findViewById(R.id.check1);
この cb を用いて「cb.isChecked()」が true ならチェック状態、false なら非チェック状
態と判定できます。チェックボックスの項目のテキストは「cb.getText()」で取得できます。
「例題 3-5」ボタンのクリックでりんご、みかん、いちごのチェックされている項目をタイ
トルバーに表示します。チェックボックスが 3 個あるので、「CheckBox cb[]=new
CheckBox[3];」のような CheckBox 型配列を用意し、cb[0],cb[1],cb[2]で 3 個のチェックボ
ックスを管理します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<CheckBox
android:id="@+id/check1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="りんご"
/>
<CheckBox
android:id="@+id/check2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="みかん"
/>
<CheckBox
android:id="@+id/check3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="いちご"
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="クリックしてね"
/>
</LinearLayout>
・MainActivity.java
package com.example.checkbox1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity
implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
}
public void onClick(View view) {
CheckBox cb[]=new CheckBox[3];
cb[0]=(CheckBox)findViewById(R.id.check1);
cb[1]=(CheckBox)findViewById(R.id.check2);
cb[2]=(CheckBox)findViewById(R.id.check3);
String msg="";
for (int i=0;i<3;i++){
if (cb[i].isChecked())
msg+=cb[i].getText()+":";
}
setTitle(msg);
}
}
「練習問題 3-5」CheckBox のチェックの判定に配列を使わずに個々に判定しなさい。
・activity_main.xml
例題 3-5 と同じ。
・MainActivity.java
package com.example.checkbox2;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity
implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
}
public void onClick(View view) {
String msg="";
CheckBox cb;
cb=(CheckBox)findViewById(R.id.check1);
if (cb.isChecked())
msg+=cb.getText()+":";
cb=(CheckBox)findViewById(
①
);
②
);
if (cb.isChecked())
msg+=cb.getText()+":";
cb=(CheckBox)findViewById(
if (cb.isChecked())
msg+=cb.getText()+":";
setTitle(msg);
}
}
3-6 ラジオボタン(RadioGroup と RadioButton)
RadioButton は RadioGroup でグループ化された各項目の中で、クリックされた 1 つを
チェック状態(ON)に、他を非チェック状態(OFF)にするウイジェットです。グループ
単位で動作するため< RadioGroup >タグの中にそのグループに属するラジオボタンを
<RadioButton>タグで定義します。初期設定でチェック状態にしておきたいラジオボタン
に「android:checked="true"」を指定します。この指定がいずれかのラジオボタンになけれ
ば、初期状態はどのラジオボタンもチェック状態にありません。
<RadioGroup・・・>
←グループの定義
<RadioButton・・・/> ←グループ内の個々のラジオボタン
<RadioButton・・・/>
</RadioGroup>
グループ内でチェックされている項目は 1 つです。この項目を取得するには次のように
します。rg.getCheckedRadioButtonId()でグループ内でチェックされているラジオボタン
の ID を取得できます。
RadioGroup rg=(RadioGroup)findViewById(R.id.radiogroup);
RadioButton rb=(RadioButton)findViewById(rg.getCheckedRadioButtonId());
rb.getText();
「例題 3-6」ボタンのクリックで、ON になっているラジオボタンの内容をタイトルバーに
表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<RadioButton
android:id="@+id/radio1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:checked="true"
android:text="男"
/>
<RadioButton
android:id="@+id/radio2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="女"
/>
</RadioGroup>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="クリックしてね"
/>
</LinearLayout>
・MainActivity.java
package com.example.radiobutton1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
}
public void onClick(View view) {
RadioGroup rg=(RadioGroup)findViewById(R.id.radiogroup);
RadioButton
rb=(RadioButton)findViewById(rg.getCheckedRadioButtonId());
setTitle(rb.getText());
}
}
「練習問題 3-6」Android、iOS、Windows という 3 項目のラジオボタンを作り、チェック
されているものをタイトルバーに表示しなさい。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<RadioButton
android:id="@+id/radio1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:checked="true"
android:text=
①
/>
<RadioButton
android:id="@+id/radio2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=
②
/>
<RadioButton
android:id="@+id/radio3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=
③
/>
</RadioGroup>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="クリックしてね"
/>
</LinearLayout>
・MainActivity.java
package com.example.radiobutton2;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
}
public void onClick(View view) {
RadioGroup rg=(RadioGroup)findViewById(R.id.radiogroup);
RadioButton
rb=(RadioButton)findViewById(rg.getCheckedRadioButtonId());
setTitle(rb.getText());
}
}
3-7 スピナー(Spinner)
Spiner はスピナーの▼ボタンのクリックでスピナーに登録されている項目をポップアッ
プ画面に表示し、その項目の中から1つを選択するウイジェットで<Spiner>タグで定義し
ます。表示される各項目はラジオボタンと同様な動作をします。スピナーに登録する項目
は android:entries 属性に指定します。
<Spinner
android:entries="@array/items"
/>
@array/items は res/values フォルダの string.xml に次のように定義した内容を指します。
<resources>
<string-array name="items">
<item>学生</item>
<item>会社員</item>
<item>主婦</item>
</string-array>
</resource>
スピナーの選択されている項目の内容は以下のようにして取得できます。
Spinner sp=(Spinner)findViewById(R.id.spinner);
sp.getSelectedItem();
取得したデータは Object 型なので、項目の内容を取得するには
(String) sp.getSelectedItem()
または
sp.getSelectedItem().toString()
とします。
選択されている項目の番号(0 スタート)は「sp.getSelectedItemPosition()」で取得で
きます。
「例題 3-7」スピナーの▼ボタンのクリックでスピナーに登録されている項目の中から 1 つ
を選択します。ボタンのクリックで、スピナーで選択されている項目の番号と内容をタイ
トルバーに表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries="@array/items"
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="選択した後でクリックしてね"
/>
</LinearLayout>
・res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Spinner1</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string-array name="items">
<item>学生</item>
<item>会社員</item>
<item>主婦</item>
</string-array>
</resources>
・MainActivity.java
package com.example.spinner1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity implements OnClickListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt1=(Button)findViewById(R.id.button1);
bt1.setOnClickListener(this);
}
public void onClick(View view) {
Spinner sp=(Spinner)findViewById(R.id.spinner);
setTitle(sp.getSelectedItemPosition()+":"+(String)sp.getSelectedItem());
}
}
「 注 」 Android 4.0 以 後 は Spinner は デ フ ォ ル ト で ド ロ ッ プ ダ ウ ン 形 式
「 android:spinnerMode="dropdown" 」 と な り ま す 。 ダ イ ア ロ グ 形 式 に す る に は
「android:spinnerMode="dialog"」とします。
「練習問題 3-7」スピナーの項目を Android、iOS、Windows、Linux の 4 項目にしなさい。
・activity_main.xml,Spinner2.java
例題 3-7 と同じ。
・res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Spinner2</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string-array name="items">
①
②
③
④
</string-array>
</resources>
3-8 リストビュー(ListView)
ListView は項目の一覧をリスト形式で表示するウイジェットで<ListView>タグで定義
します。リスト項目の登録の仕方はスピナーの場合と同じです。
<ListView
android:entries="@array/items"
/>
1.
OnItemClickListener
リストビューでは通常、リスト項目の選択というイベントで処理を行います。そこでリ
ストビューには次のようにして OnItemClickListener を設定します。
ListView lv=(ListView)findViewById(R.id.listview);
lv.setOnItemClickListener(new ItemClick());
class ItemClick implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
リスト項目が選択されたときの処理
}
}
選択された項目は onItemClick メソッドの parent と position 引数を使って次のように取
得します。
String item=(String)((ListView)parent).getItemAtPosition(position);
「注」ラジオボタン、チェックボックス、スピナーはクリックしたときの選択状態を保持
しているので、これらのウイジェットの直接のクリックイベントでなく、ボタンのクリッ
クイベントで、これらのウイジェットの選択状態を取得できました。ところがリストビュ
ーは項目をクリックしたとき、選択状態などを保持できません。そのためリストビュー自
体にイベントリスナーを設定します。
2.
ジェネリッククラス
クラス名の右に「<T>」という「型パラメーター」を指定したクラスをジェネリッククラ
スと呼びます。たとえば List クラスは Integer、String などのデータ要素をリストとして
扱うことができるジェネリッククラスです。使用する場合は<>内にデータ型を指定します。
List<String> list = new ArrayList<String>();
list.add(new String("Ann"));
String x =list.get(0);
ListView、Spinner は AdapterView のサブクラスです。このため onItemClick メソッド
の第 1 引数は「AdapterView<?> parent」です。(ListView) parent のように実際のクラス
にキャストしてから使います。さてここで AdapterView はジェネリッククラスですが、型
パラメータは<?>となっています。<?>はワイルドカードで無名のオブジェクト型を示しま
す。コンパイル時には型を特定せず、実行時に渡された型を適用することを意味します。
「例題 3-8」リストビューで選択された項目の内容をタイトルバーに表示します。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries="@array/items"
/>
</LinearLayout>
・strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Listview1</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string-array name="items">
<item>学生</item>
<item>会社員</item>
<item>主婦</item>
</string-array>
</resources>
・MainActivity.java
package com.example.listview1;
import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.view.View;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv=(ListView)findViewById(R.id.listview);
lv.setOnItemClickListener(new ItemClick());
}
class ItemClick implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view,int position,
long id) {
String item =(String) ((ListView)
parent).getItemAtPosition(position);
setTitle(item);
}
}
}
「練習問題 3-8」
「学生、会社員、主婦」の次に「男、女」のリストビューを追加しなさい。
各リストビューの選択項目は TextView に表示しなさい。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@+id/listview1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries="@array/items1"
/>
<TextView
android:id="@+id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@+id/listview2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
①
android:entries=
/>
</LinearLayout>
・strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Listview2</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string-array name="items1">
<item>学生</item>
<item>会社員</item>
<item>主婦</item>
</string-array>
<string-array
②
>
<item>男</item>
<item>女</item>
</string-array>
</resources>v
・MainActivity.java
package com.example.listview2;
import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.view.View;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv1=(ListView)findViewById(R.id.listview1);
lv1.setOnItemClickListener(new ItemClick1());
ListView lv2=(ListView)findViewById(R.id.listview2);
lv2.setOnItemClickListener(new ItemClick2());
}
class ItemClick1 implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view,int position,
long id) {
String item =(String) ((ListView)
parent).getItemAtPosition(position);
TextView text1=(TextView)findViewById(R.id.text1);
text1.setText(item);
}
}
class ItemClick2 implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view,int position,
long id) {
String item =(String) ((ListView)
parent).getItemAtPosition(position);
TextView text2=(TextView)findViewById(R.id.text2);
text2.setText(item);
}
}
}
6-2 ビュー画面への描画
1.
invalidate メソッド
タッチイベントの発生で呼び出されるメソッド内では直接ビュー画面への描画を行うこ
とができません。このため GView クラスの gv をメンバ変数として宣言しておき、
gv.invalidate メソッドを使って onDraw メソッドを呼び出すことでビュー画面への描画を
行います。
2.
ビュー画面のトップ位置
Android の通常の画面構成は画面上端からステータスバー、タイトルバーがあり、その下
にビュー画面があります。タッチイベントの「event.getY();」で取得した y 座標の原点は画
面の上端を原点にした値ですので、この値を元にビュー画面に表示する場合は補正が必要
になります。この補正をする値はステータスバーとタイトルバーの高さの合計です。これ
らの高さを求める方法はいくつかありますが、ステータスバーとタイトルバーの高さを
個々に求める代わりに画面上端からビュー画面のトップ位置までの距離は以下で得られま
す。なお、この値は onCreate メソッド内や Gview コンストラクタ内では画面構成が完成
していないため 0 となってしまいますので、onDraw メソッド内で取得しています。
float top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
したがってタッチイベントで得らられる「event.getY();」からこの top を引いた値をビュ
ー画面の y 座標として使えばよいことになります。なお、ステータスバー、タイトルバー
を消してフルスクリーンモードにすればこのような補正は必要ありません。
「例題 6-2」ビュー画面の左上隅からタッチムーブ位置に直線を描きます。(px,py)がタッチ
位置です。
・MainActivity.java
package com.example.touch3;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.*;
public class MainActivity extends Activity {
private float px=0,py=0;
private GView gv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
}
private class GView extends View {
private Paint paint;
public GView(Context context) {
super(context);
paint=new Paint();
}
protected void onDraw(Canvas canvas) {
float
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
paint.setColor(Color.BLUE);
canvas.drawLine(0,0,px,py-top,paint);
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_MOVE){
px=event.getX(); // タッチ位置をメンバ変数に格納
py=event.getY();
gv.invalidate(); // 再描画
}
return super.onTouchEvent(event);
}
}
「練習問題 6-2」タッチムーブ位置にイメージを追従して移動しなさい。
・MainActivity.java
package com.example.touch4;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.*;
public class MainActivity extends Activity {
private float px=0,py=0;
private GView gv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
}
private class GView extends View {
private
①
public GView(Context context) {
super(context);
img=BitmapFactory.decodeResource(getResources(),R.drawable.sai);
}
protected void onDraw(Canvas canvas) {
float
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
canvas.drawBitmap(
②
,null);
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_MOVE){
px=event.getX();
py=event.getY();
gv.invalidate();
}
return super.onTouchEvent(event);
}
}
6-3 画面サイズ
画面の幅と高さは onDraw メソッドの canvas 引数を使って canvas.getWidth()と
canvas.getHeight()で取得できます。得られる高さにはステータスバーとタイトルバーの高
さの合計が含まれていますので、描画できる画面の高さは以下のように top を引いた値とな
ります。
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
h=canvas.getHeight()-top;
「例題 6-3」画面中央に羅針盤を置き、タッチ位置から北東、南東、南西、北西の 4 方向を
判定します。
・MainActivity.java
package com.example.touch5;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.*;
public class MainActivity extends Activity {
private float w,h,top;
private GView gv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
}
private class GView extends View {
private Bitmap img;
public GView(Context context) {
super(context);
img=BitmapFactory.decodeResource(getResources(),R.drawable.compass);
}
protected void onDraw(Canvas canvas) {
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
w=canvas.getWidth();
h=canvas.getHeight()-top;
canvas.drawBitmap(img,w/2-img.getWidth()/2,h/2-img.getHeight()/2,null);
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_MOVE){
float px=event.getX();
float py=event.getY()-top;
if (px>w/2 && py<h/2)
setTitle("北東");
else if (px>w/2 && py>h/2)
setTitle("南東");
else if (px<w/2 && py>h/2)
setTitle("南西");
else if (px<w/2 && py<h/2)
setTitle("北西");
}
return super.onTouchEvent(event);
}
}
「注」画面の幅と高さは View クラスの getWidth メソッド、getHeight メソッドで取得で
きます。これらのメソッドは Gview コンストラクタ内では幅と高さが確定していないので
値を取得できません。onDraw メソッド内で取得します。
int w=getWidth();
int h=getHeight();
Canvas クラスの getWidth メソッド、getHeight メソッドを使って次のように取得する
こともできます。ただしこの場合、幅は View クラスの getWidth メソッドと同じですが、
高さはステータスバーとタイトルバーの高さも含んでいます。
int w=canvas.getWidth();
int h=canvas.getHeight();
画面サイズを別の方法で求めるには 11 章-「11-8 ブラウザ(WebView)」の「「注」
Display クラスの getWidth()と getHeight()」を参照。
「練習問題 6-3」
1~8 のイメージを画面中央を中心とする半径 160 の円周上に配置します。
タッチ位置を元にタッチしたイメージを判定しなさい。
・MainActivity.java
package com.example.touch6;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.*;
public class MainActivity extends Activity {
private int[] imageId={
R.drawable.num1,R.drawable.num2,R.drawable.num3,R.drawable.num4,
R.drawable.num5,R.drawable.num6,R.drawable.num7,R.drawable.num8
};
private float w,h,top,iw,ih;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GView(this));
}
private class GView extends View {
public GView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
w=canvas.getWidth();
h=canvas.getHeight()-top;
for (int i=0;i<8;i++){
Bitmap
img=BitmapFactory.decodeResource(getResources(),imageId[i]);
float x=(float)(160*Math.cos(45*i*Math.PI/180));
float y=(float)(160*Math.sin(45*i*Math.PI/180));
iw=img.getWidth();
ih=img.getHeight();
canvas.drawBitmap(img,
①
,h/2-y-ih/2,null);
}
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
float px=event.getX();
float py=event.getY()-top;
for (int i=0;i<8;i++){
float x=(float)(160*Math.cos(45*i*Math.PI/180));
float y=(float)(160*Math.sin(45*i*Math.PI/180));
if (
②
&& px<w/2-x+iw/2 && h/2-y-ih/2<py && py<h/2-y+ih/2)
setTitle("No"+(i+1));
}
}
return super.onTouchEvent(event);
}
}
「 注 」 Bitmap img=BitmapFactory.decodeResource(getResources(),imageId[i]); は
onDraw メソッド内に置いているので 2-1 の「注」Android Lint Checks と 2-4 の「注」Android
Lint Checks で示した理由により警告エラーとなります。onDraw メソッド外でリソースを作成
すればよいのですが、煩雑になるため、ここでは onDraw 内に置きました。
☆応用サンプル 羅針盤の針を回す
タッチムーブ位置の方向を指すように針を回転させます。羅針盤 compass と針 needle
を画面中央に描画します。画面の中央位置を(w,h)に取得し、「canvas.translate(w,h);」で
画面中央に座標移動します。針の角度 angle はタッチ位置(x,y)からアークタンジェントを
使って「Math.atan(y/x)*180/Math.PI」で求め、「canvas.rotate(angle);」で座標回転しま
す。
・MainActivity.java
package com.example.compass;
import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.*;
import android.view.*;
public class MainActivity extends Activity
{
private GView gv;
private int w,h;
private float angle=0,top=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
}
private class GView extends View {
private Bitmap needle,compass;
public GView(Context context) {
super(context);
needle=BitmapFactory.decodeResource(getResources(),R.drawable.needle);
compass=
BitmapFactory.decodeResource(getResources(),R.drawable.compass);
}
protected void onDraw(Canvas canvas) {
top=getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
w=getWidth()/2;
h=getHeight()/2;
canvas.drawColor(Color.WHITE);
canvas.translate(w,h);
canvas.drawBitmap(compass,-compass.getWidth()/2,
-compass.getHeight()/2, null);
canvas.rotate(angle);
canvas.drawBitmap(needle,-needle.getWidth()/2,
-needle.getHeight()/2, null);
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_MOVE){
float x=event.getX()-w;
float y=event.getY()-top-h;
angle=(float)(Math.atan(y/x)*180/Math.PI);
if (x<0)
angle+=180;
gv.invalidate();
}
return super.onTouchEvent(event);
}
}
7-2 アラート・ダイアログ
AlertDialog はユーザに何らかの処理に対する問い合わせ(OK や CANCEL など)を行
うダイアログクラスです。
1.
AlertDialog.Builder
AlertDialg のコンストラクタには直接アクセスできませんので、以下のように
AlertDialog.Builder クラスのオブジェクト builder を使ってアラート・ダイアログの内容
を設定します。
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("確認");
builder.setMessage("処理してよいですか");
2.
ボタンのリスナーの設定
AlertDialog の OK ボタンをクリックしたときのリスナーは setPositiveButton メソッド
を使って以下のように設定します。同様に CANCEL ボタンのリスナーは
setNegativeButton メソッドを使って設定します。
builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
OK ボタンがクリックされたときの処理
}
});
3.
ダイアログの表示
上の 1、2 で設定したアラートダイアログ・ビルダーの builder を使って、AlertDialg ク
ラスのオブジェクト dialog を生成し show メソッドで表示します。
AlertDialog dialog=builder.create();
dialog.show();
4.
アイコン
「builder.setIcon(R.drawable.tab1);」でアイコンを指定できます。サイズは mdpi で 32
×32 とします。
5.
Neutral ボタン
ボタンは NegativeButton,NeutralButton,PositiveButton の順に並びます。
builder.setNeutralButton("Neutral",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("Neutral");
}
});
「注」Android 2.x ではボタンは PositiveButton、NeutralButton、NegativeButton の順
に並びます。
「例題 7-2」画面のタッチでアラート・ダイアログを表示します。OK、CANCEL ボタンの
クリックでどちらのボタンがクリックされたのかのメッセージをタイトルバーに表示しま
す。
・MainActivity.java
package com.example.alert1;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("確認");
builder.setMessage("処理してよいですか");
builder.setPositiveButton("OK",new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("OK");
}
});
builder.setNegativeButton("CANCEL", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("CANCEL");
}
});
AlertDialog dialog=builder.create();
dialog.show();
}
return super.onTouchEvent(event);
}
}
「練習問題 7-2」例題 7-2 にアイコンと Neutral ボタンを追加しなさい。
・MainActivity.java
package com.example.alert2;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("確認");
builder.setMessage("処理してよいですか");
builder.setIcon(
①
);
builder.setPositiveButton("OK",new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("OK");
}
});
builder.setNegativeButton("CANCEL", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("CANCEL");
}
});
builder.
②
("Neutral",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle("Neutral");
}
});
AlertDialog dialog=builder.create();
dialog.show();
}
return super.onTouchEvent(event);
}
}
☆応用サンプル 食文化判定
質問項目を示す 2 分木の項目ノードが node[ ]に、左、右へのポインタが left[ ],right[ ]
に格納されています。ノード位置を p で示し、ルートノード(p=0)から初めて left[p]また
は right[p]が「-1」になるまで木を進みます。質問項目はアラート・ダイアログで表示し、
「Yes」ボタンで左の木へ進み、「No」ボタンで右の木へ進みます。
・MainActivity.java
package com.example.tree1;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends Activity {
private String node[]={
"お米が好きですか",
"味噌汁が好きですか",
"パスタが好きですか",
"あなたは和食派です",
"あなたは中華派です",
"あなたはイタリアンです",
"あなたはフレンチです"};
private int left[]={1,3,5,-1,-1,-1,-1};
private int right[]={2,4,6,-1,-1,-1,-1};
private static int p=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("食文化判定");
builder.setPositiveButton("Yes",new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
p=left[p];
if (p==-1){
p=0;
}
else {
builder.setMessage(node[p]);
builder.create().show();
}
}});
builder.setNegativeButton("No", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
p=right[p];
if (p==-1){
p=0;
}
else {
builder.setMessage(node[p]);
builder.create().show();
}
}});
builder.setMessage(node[p]);
builder.create().show();
}
return super.onTouchEvent(event);
}
}
10-3 イメージを画面上で移動する
一定時間ごとの処理の具体例として、イメージを画面上で移動します。
1.
ボールの移動
ボールのイメージファイルは ball.png、サイズは 10×10 ピクセル、1 回にボールが進む
距離は 10 ピクセルとします。ボールの位置(左上隅)を x,y、移動量を dx,dy とすると、
ボールを左右に移動するには「x+=dx」、ボールを上下に移動するには「y+=dy」とします。
斜めに移動する場合は「x+=dx」と「y+=dy」の両方を行います。
2.
壁にボールがあたったときの判定
ボールが左右壁にあたったときに dx の値の符号を反転するには次のようにします。w は
画面の幅です。10 はボールのサイズです。
if (x<=0 || w-10<=x)
dx=-dx;
ボールが上下壁にあたったときに dy の値の符号を反転するには次のようにします。h は
画面の高さです。
if (y<=0 || h-10<=y)
dy=-dy;
「例題 10-3」ボールを 100 ミリ秒単位で横方向に移動し、左右壁でボールを跳ね返します。
・MainActivity.java
package com.example.handler5;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.*;
import android.graphics.*;
public class MainActivity extends Activity implements Runnable{
private int x=60,dx=10,w;
private Handler hd=new Handler();
private GView gv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
hd.post(this);
}
public void run() {
x+=dx;
if (x<=0 || w-10<=x)
dx=-dx;
gv.invalidate();
hd.postDelayed(this,100);
}
class GView extends View {
private Bitmap ball;
public GView(Context context) {
super(context);
ball=BitmapFactory.decodeResource(getResources(),R.drawable.ball);
}
public void onDraw(Canvas canvas){
w=getWidth();
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(ball,x,60,null);
}
}
}
「練習問題 10-3」ボールを 100 ミリ秒単位で斜めに移動し、上下壁、左右壁でボールを跳
ね返しなさい。
・MainActivity.java
package com.example.handler6;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.*;
import android.graphics.*;
public class MainActivity extends Activity implements Runnable{
private int x=60,y=60,dx=10,dy=10,w,h;
private Handler hd=new Handler();
private GView gv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
hd.post(this);
}
public void run() {
x+=dx;y+=dy;
if (x<=0 || w-10<=x)
dx=-dx;
if (
①
)
dy=-dy;
gv.invalidate();
hd.postDelayed(this,100);
}
class GView extends View {
private Bitmap ball;
public GView(Context context) {
super(context);
ball=BitmapFactory.decodeResource(getResources(),R.drawable.ball);
}
public void onDraw(Canvas canvas){
w=getWidth();
h=
②
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(ball,x,y,null);
}
}
}
☆応用サンプル ラケットゲーム 1
タッチムーブイベントでラケットを移動し、ボールを跳ね返します。「練習問題 10-3」
を元にラケットの移動処理とボールをラケットで跳ね返す処理を追加します。ボールがラ
ケットに当たったを判定するのに y 座標に関する等価比較を行うため、ラケットの y 座標
はボールの移動量の 10 の倍数とします。画面の高さを元に以下で計算します。
ry=(getHeight()/10)*10-100;
ボールとラケットのイメージのサイズは以下で計算します。ボールの高さと幅は同じと仮
定しています。
ballW=ball.getWidth();
barW=bar.getWidth();
・MainActivity.java
package com.example.racket1;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.*;
import android.graphics.*;
public class MainActivity extends Activity implements Runnable{
private int x=100,y=100,dx=10,dy=10,rx=100,ry,w,ballW,barW;
private GView gv;
private Handler hd=new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv=new GView(this);
setContentView(gv);
hd.post(this);
}
public void run() {
x+=dx;y+=dy;
if (x<=0 || w-ballW<=x)
dx=-dx;
if (y<=0)
dy=-dy;
if (rx-ballW<=x && x<=rx+barW && y+ballW==ry) // ラケットで跳ね返す
dy=-dy;
gv.invalidate();
hd.postDelayed(this,100);
}
class GView extends View {
private Bitmap ball,bar;
public GView(Context context) {
super(context);
ball=BitmapFactory.decodeResource(getResources(),R.drawable.ball);
bar=BitmapFactory.decodeResource(getResources(),R.drawable.bar);
ballW=ball.getWidth();
barW=bar.getWidth();
}
public void onDraw(Canvas canvas){
w=getWidth();
ry=(getHeight()/10)*10-100;
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(ball,x,y,null);
canvas.drawBitmap(bar,rx,ry,null);
}
}
public boolean onTouchEvent(MotionEvent event) { // ラケットの移動
if (event.getAction()==MotionEvent.ACTION_MOVE){
rx=(int)event.getX()-barW/2;
if (rx<barW/2)
rx=0;
if (rx>w-barW)
rx=w-barW;
gv.invalidate();
}
return super.onTouchEvent(event);
}
}
17-2 複数のテキストを読み上げる
txt[ ]配列の読み上げテキストが行単位で格納されているとき、行間に 1 秒のサイレント
を入れるには以下のようにします。なお、複数のテキストを連続して読み上げる場合は
「QUEUE_ADD」モードにします。「QUEUE_FLUSH」モードだと最後のテキストしか
読み上げられません。
for (int i=0;i<n;i++){
ts.speak(txt[i],TextToSpeech.QUEUE_ADD,null);
ts.playSilence(1000,TextToSpeech.QUEUE_ADD,null);
}
「例題 17-2」複数のテキストを、行間に 1 秒のサイレントを入れて読み上げます。
・MainActivity.java
package com.example.speech2;
import java.util.Locale;
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.MotionEvent;
import android.widget.*;
public class MainActivity extends Activity implements OnInitListener{
private TextToSpeech ts;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ts=new TextToSpeech(this,this);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
String txt[]={"Good morning","Hello","Good night"};
if (ts.isSpeaking()) ts.stop();
ts.setSpeechRate(1.0f);
for (int i=0;i<txt.length;i++){
ts.speak(txt[i],TextToSpeech.QUEUE_ADD,null);
ts.playSilence(1000,TextToSpeech.QUEUE_ADD,null);
}
}
return super.onTouchEvent(event);
}
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
Locale locale=Locale.ENGLISH;
if (ts.isLanguageAvailable(locale)>=TextToSpeech.LANG_AVAILABLE)
ts.setLanguage(locale);
else
Toast.makeText(this,"この言語は未サポートです
",Toast.LENGTH_LONG).show();
}
else
Toast.makeText(this,"音声合成できません",Toast.LENGTH_LONG).show();
}
protected void onDestroy(){
super.onDestroy();
if (ts!=null) ts.shutdown();
}
}
17-3 通訳アプリ
音声合成機能を使って簡単な通訳アプリを作ることができます。
「例題 17-3」ListView に登録した日本語に対応する英語を読み上げます。
・activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
・MainActivity.java
package com.example.speech3;
import java.util.Locale;
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity implements OnInitListener{
private TextToSpeech ts;
private String[] Japanese={
"おはよう","こんにちは","おやすみ","ありがとう",
"お名前は","お値段は","すみません","美味しいです",
"何時ですか","友達になってください","何をお求めですか",
"病院はどこですか","お茶を飲みましょう","もう一度言って下さい"};
private String[] English={
"Good morning","Hello","Good night","Thank you",
"What is the name?","How much is a price?","I'm sorry","I am delicious",
"What time is it?","Please make friends","What is it a request in?",
"Where is the hospital?","Let's drink tea","Please say once again"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1);
for (int i=0;i<Japanese.length;i++)
adapter.add(Japanese[i]);
ListView lv=(ListView)findViewById(R.id.listview);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position,
long id) {
if (ts.isSpeaking()) ts.stop();
ts.setSpeechRate(1.0f);
ts.speak(English[position],TextToSpeech.QUEUE_FLUSH,null);
}
});
ts=new TextToSpeech(this,this);
}
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
Locale locale=Locale.ENGLISH;
if (ts.isLanguageAvailable(locale)>=TextToSpeech.LANG_AVAILABLE)
ts.setLanguage(locale);
else
Toast.makeText(this,"この言語は未サポートです",
Toast.LENGTH_LONG).show();
}
else
Toast.makeText(this,"音声合成できません", Toast.LENGTH_LONG).show();
}
protected void onDestroy(){
super.onDestroy();
if (ts!=null) ts.shutdown();
}
}