第3回 Get Input from the User / ユーザーから入力を取得する

最終更新日:2025年04月29日

ホームへ戻る

第2回のプロジェクト、"LG First Android GUI" 、を続けて使用する。

第3回の提出課題一覧

【チェック合格条件】各スクリーンショットと内容が一致すること(色は問わない)
  • 演習問題3_1:図1と同じ画面構成と画面遷移ができること(必須)
  • 演習問題3_2:(必須)
  • 演習問題3_3:(必須)
  • 演習問題3_4(任意)

演習問題3_1: Clickable image から他の Activity を立ち上げる

  1. 下記「A. Clickable images」の説明を参考に、レイアウトの左下に【設定画面】を開くための  FloatingActionButton  型ボタンを追加する。アイコンを図1左下と同じ形(歯車マーク)のものにする(色、大きさは問わない)。
  2. SetActivity という名の新しい "Empty Views Activity" を作成する。
    1. SetActivity のレイアウトの名を activity_set とする。
    2. SetActivity のタイトルを "Settings" とする。
    3. SetActivity の戻る(ホーム)ボタンを表示させる。
  3. 下記「B. Activity callback」の説明を参考に、「a」で作成した【設定】ボタンをタップた際
    1. SetActivity を起動させる。
    2. “opening user setting”を表示する Toast を表示させる。
    3. SetActivity の戻る(ホーム)ボタンをタップした時、アクティビティが終了finish() メソッド)し、再び MainActivity が表示されるようにする。

演習問題3_1で実装するUIと機能の遷移状態は図1にまとめている。

setting_open-close.png
図1.課題3_1を実行したときの画面構成(左はMainActivity、右はSetActivity)と機能遷移

前提知識

この課題で学ぶこと

A. Clickable images / クリック可能な画像

概要

Android搭載デバイスの画面に表示されるユーザーインターフェイス(UI)は、ビュー(View)と呼ばれるオブジェクトの階層で構成されている。 画面のすべての要素はViewである。Viewクラスは、すべてのUIコンポーネントの基本的な構成要素を表す。 Viewは、Button要素をはじめとするインタラクティブなUIコンポーネントを提供するクラスの基本クラスである。
Buttonは、ユーザーがタップまたはクリックしてアクションを実行できるUI要素です。
ImageViewなどの任意のViewをタップまたはクリックできるUI要素に変えることができます。ImageViewの画像は、プロジェクトのdrawablesフォルダーに保存する必要があります。
この実習では、ユーザーがタップまたはクリックできる要素として画像を使用する方法を学習します。

FloatingActionButtonの追加

AndroidStudioのアイコンのセットからアイコンを選択できます。次の手順を実行します:

  1. Project > Androidパネルで res (リソース)を展開し、 drawable フォルダーを右クリック
  2. New > Image Asset を選択し、イメージアセット設定ダイアログが表示される
  3. ダイアログの上部にあるドロップダウンメニューで Action Bar と Tab Icons を選択
  4. 「名前」フィールドのic_action_nameを ic_set に変更
  5. クリップアート画像をクリックして、以下の クリップアート画像をアイコンとして選択
    ic_set.png
  6. Theme ドロップダウンメニューから CUSTOM/HOLO_DARK/HOLO_LIGHT のどちらかを選択する。これにより、アイコンが暗い色(または黒)の背景に対して白に設定される。Next をクリックする。
  7. 次のダイアログで 完了/Finish をクリックする。
  8. Layout Editor のデザインモードにおいて、Palette の Buttons カテゴリーから FloatingActionButton を選択し、以下のスクリーンショットと同じ位置におく。
    アイコン選択の際、Drawable の中に先ほど追加したアイコンを選定
screenshot_1.png
図2.Floating Action Buttonの配置

B. Activity callback / 他 Activity の起動と終了

Activity の追加

前のレッスンで学習したように、アクティビティは、ユーザーが単一の焦点を絞ったタスクを実行できるアプリ内の単一の画面を表す。 MainActivity.javaという1つのアクティビティがすでにある。 次に、SetActivity.javaという別のアクティビティを追加する。
左側の列にあるjp.aoyama.t23428.lgfirstandroidguiフォルダーを右クリック(またはControlキーを押しながらクリック)して、[New]> [Activity]> [Empty Views Activity] を選択する。 アクティビティ名をSetActivityに、レイアウト名をactivity_setに編集します。 他のオプションはそのままにして、[完了]をクリックする。
これで、SetActivityクラスがMainActivityと一緒にjavaフォルダーにリストされ、activity_set.xmllayout フォルダーにリストされるはず。

Action の変更

このステップでは、FloatingActionButton のアクションを変更して、新しい Activity を起動する。

  1. MainActivity.java を開く
  2. 設定アイコンをタップした際、 SetActivity が起動されるよう、myBtnClick(View view)メソッド(演習課題2で作成しているはずですが、設定ボタン専用のクリック処理メソッドを作成しても良い)に明示的 Intent の作成コードを追加する(必要に応じて else if 文に囲めて):
  3.   
    	Intent intent = new Intent(MainActivity.this, SetActivity.class);
    	startActivity(intent);
      
    
  4. アプリを実行し、設定アイコンを使用する floating action button をタップすると、空白の Activity (SetActivity)が表示されることを確認。
  5. SetActivity を終了させ、呼び出した Activity(MainActivity)に戻るには、 finish() メソッドを使う。今回は、SetActivityの「戻る」ボタンのタップで終了させる。

Toast の作成

このタスクでは、画像・ボタンがタップされた際示すToastメッセージを表示する方法を学ぶ。

  1. string.xml リソースに Toast が表示するメッセージ、"opening user setting"、を用意する。
  2. MainActivity を開き、以下の displayToast() メソッドを追加する。 
  3. 
    	public void displayToast(String message) {
    		Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    	}
    
    
  4. myBtnClick() メソッド内に、作成した displayToast() メソッドの呼び出しを、設定ボタンのクリック時コードに追加し、メソッドの属性に string.xml に用意した文字列が入るようにする。
  5. 
    	public void myBtnClick(View v) {
    		/** 設定ボタンのクリック処理に追加する **/
    		displayToast(getString(xxxxxxxxx));
    	}
      
    

演習問題3_2:

「Input Control」の説明を参考にしながら、UI が図2~4と同じになるように、「a」~「g」の要素と機能を実装する。
  1. 端末/エミュレータの設定にて言語を「英語(米国)」を追加し、キーボードをQwerty に指定する(Gboard)。
  2. 名前を入力するフィールドは、Layout Editor の Palette の「PlainText」要素で作成する。名前の頭文字が自動的に大文字入力になるため、属性(attributes)の inputType を適切に設定する。
  3. 学生番号を入力フィールドは、Layout Editor の Palette の「Number」要素で作成する。そうすることで、入力の際テンキーが自動で表示される。
  4. メールアドレスを入力フィールドは、Layout Editor の Palette の「E-mail」要素で作成する。そうすることで、入力の際キーボードに「@」キーが自動で表示される。
  5. 電話番号を入力するフィールドは、Layout Editor の Palette の「Phone」要素で作成する。そうすることで、入力の際テンキーが自動で表示される。
  6. 電話番号の種類は、家・仕事・携帯・その他」の4つの選択肢を用意する。そのため、Layout Editor の Palette の widget カテゴリにある「spinner 」を利用する。電話番号の種類を選定・変更する度に、選択した種類の名前が Toast で表示されるようにする。
  7. 通学手段(Mobility)は「RadioButton」で作成する(横並び、縦並び、どちらでもOK)。1つの RadioButton しか選択できないように、「RadioGroup」で囲むこと。RadioButton の onClick ハンドラーを設定し、選択する度、どのボタンが選択されたかを Toast を用いて表示させる。
exercise3_2_name.png
図3.課題3_2の完成時スクリーンショット(Name入力時)
exercise3_2_e-mail_mobile.png
図4.課題3_2の完成時スクリーンショット(e-mail入力時)
exercise3_2_phone_home.png
図5.課題3_2の完成時スクリーンショット(電話番号入力時)

Input Control / 入力コントロール

概要 / Introduction

ユーザーがテキストまたは数字を入力できるようにするには、EditText 要素を使用する。
一部の入力コントロールは、表示されるキーボードのタイプを定義するEditText属性であり、ユーザーがデータを簡単に入力できるようにしている。たとえば、android:inputType 属性に [phone] を選択すると、文字キーボードの代わりにテンキーを表示することができる。

他の入力コントロールにより、ユーザーは簡単に選択できる。たとえば、RadioButton 要素を使用すると、ユーザーはアイテムのセットから1つ(そして1つだけ)のアイテムを選択できる。

この課題では、属性を使用して画面上のキーボードの外観を制御し、EditTextのデータ入力のタイプを設定する。 また、SetActivityアプリに radio button を追加して、ユーザーが一連のアイテムから1つのアイテムを選択できるようにする。

この課題で学ぶこと

Radio buttons の利用とイベント取得

Radio buttons は複数の選択肢の内1つのみのオプションを選択したいとき役に立つ入力コントロール要素です。 Spinnerと比べて、すべての選択肢が一度に見える。
SetActivity に radio buttons を追加するには、まず Layout Editor を用いて activity_set.xml レイアウトに RadioButton 要素を追加する。
Radio buttons の選択は相互に排他的であるため、RadioGroup 内でそれらをグループ化し、グループ化することにより、Android システムは一度に1つのラジオボタンのみを選択できるようにする。

Radio buttons のクリック(選択)イベントを取得するため、通常のボタンと同じく、Layout File 内の各 RadioButton 要素に対して、onClick 属性を設定する(下記例を参照)。


	android:onClick="onRadioButtonClicked"
	

各 radio button 要素の android:onClick 属性において、クリックイベントを処理するため onRadioButtonClicked() メソッドを指定すれば、SetActivity クラスに新しい onRadioButtonClicked() メソッドを追加する必要がある。(下記参照)。


	public void onRadioButtonClicked(View view) {
		// Is the button now checked?
		/** ここで必要なコードを書く **/
        
		// Check which radio button was clicked.
		/** ここで必要なコードを書く **/
        
	}

Spinner の利用とイベント取得

Spinner は、セットから1つの値を選択する簡単な方法を提供する。Spinner をタッチすると、使用可能なすべての値を含むドロップダウンリストが表示され、ユーザーはそこから1つを選択できる。
2つまたは3つの選択肢しか提供していない場合、レイアウトに余裕があれば、選択肢に radio buttons を使用することをお勧めする。ただし、3つ以上の選択肢がある場合、Spinner は非常にうまく機能し、必要に応じてスクロールしてアイテムを表示し、レイアウトのスペースをほとんど占有しない。

電話番号(自宅、職場、携帯電話、その他など)のラベルを選択する方法を提供するために、アプリの SetActivity レイアウト(activity_set.xml)に Spinner を追加して、電話番号フィールドのすぐ横に表示することができる。
Spinner を追加するには、まず Layout Editor を用いて activity_set.xml レイアウトに Spinner 要素を追加する。

Spinner の選択結果イベントを取得するため、onClick ではなく、Listener を用いる。 Spinner とそのリスナーをアクティブ化するには、AdapterView.OnItemSelectedListener インターフェイスを実装する。これには、onItemSelected() および onNothingSelected() コールバックメソッドも追加する必要がある。また、Spinnerオブジェクトに対して setOnItemSelectedListener(this) メソッドを呼び出すことで、そのSpinnerオブジェクトとListenerとなったclassを対応させる。


public class SetActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
		//...
    protected void onCreate(Bundle savedInstanceState) {
        //...
        Spinner spinner = (Spinner) findViewById(R.id.spinner);
        spinner.setOnItemSelectedListener(this);
        //...
    }
    //...
}

strings.xml を開き、Spinner の選択可能な値(Home、Work、Mobile、およびOther)を文字列配列 labels_array として定義する。


	<string-array name="labels_array">
        <item>Home</item>
        <item>Work</item>
        <item>Mobile</item>
        <item>Other</item>
	</string-array>	
	

Spinner の選択コールバックを定義するには、SetActivity クラスを変更して、次のようにAdapterView.OnItemSelectedListenerインターフェイスに必要な onItemSelected() メソッドを実装する。この例では、空の onNothingSelected() コールバックメソッドにコードを追加する必要はありません。
getItemAtPosition() を使用して spinner で選択したアイテムを取得し、そのアイテムを spinnerLabel 変数に割り当てる。


	@Override
	public void onItemSelected(AdapterView adapterView, View view, int i, long l) {
		spinnerLabel = adapterView.getItemAtPosition(i).toString();
		/** Toast 表示コードを追加する **/
	}

	@Override
	public void onNothingSelected(AdapterView adapterView) { }
   

より詳しい情報は Android Developers Guide を参照すること。


演習問題3_3:Saving data into a Bundle

「Androidでのデータ永続化」の説明を参考にしつつ、Bundle型 static 変数を用いて、「a」~「d」を実装する。
  1. 入力した情報を保存するための Floating Action Button を用意する(図6を参照:フロッピーディスク形状)。
  2. 保存ボタンをタップしたときと、Action Bar の「戻る」ボタンをタップしたとき、各フィールドの値を Bundle Class static 変数に保存する。
  3. また、MainActivity より SetActivity を呼び出した際、2回目以降(Bundle 変数はnullではなく、データ入っている状態)、Bundle に保存した値で、各フィールドを自動的に入力・設定する(Fieldの種類によって、入力・設定の仕方が少し変わる)。
  4. 初回設定(SetActivity)を起動する際、図5、2回目以降図6のようになっていることを確認する。

【hint】フィールドによって、「c」で自動入力しやすいように、Bundle に保存するべき内容を考えること。

exercise3_2_e-mail_mobile.png
図5.課題3_3において、ActivitySetを初めて表示した際のスクリーンショット
exercise3_3_input.png
図6.課題3_3の完成時スクリーンショット(データ入力後、2回目の呼び出し)

Androidでのデータ永続化

Bundle について / How to use Bundle

Android には Activityのライフサイクルがあります。
別のActivityが前面に来るなどにして、メモリが不足した場合にActivityが破棄されることがある。
このとき、メモリ上にだけ展開されていたインスタンス変数などの値も破棄されてしまう。
再度呼び出されるときは、もう一度Activityを生成しなおすため、前回の状態は失われている。
そこで、前回と同じ状態に復元できるようにするために、状態を保存、復元するクラスとしてAndroidが準備してくれているのがBundleです。
簡単に言うとBundleはOSの判断で強制的に停止、終了する時に一時的にデータを格納するクラスです。
作成は以下の手順で行う。


	Bundle 変数 = new Bundle();
	変数.putString("キー1", "文字列1");
	変数.putInt("キー2", 数字1);
値を受け取る場合は以下の手順で行う。

	String 変数 = args.getString("キー1");
	int 変数 = args.getInt("キー2");

 

演習問題3_4:Saving data with shared preferences(任意)

  1. SharedPreference を用いて、設定を一度しか入力しなくて済むようにする。
    Activity 変更したり、アプリを閉じたりしても、再び「設定」を開いた際、保存した内容が自動入力(表示)される。

SharedPreferencesでデータを永続化する / Save the default values in shared preferences

アプリは、ユーザーがアプリを開いたときに、設定ごとにSharedPreferencesファイルに各値を保存する必要がある。比較的小さなコレクションの Key-Value を保存する場合は、SharedPreferences を使用することをおすすめします。

SharedPreferences とは、boolean, float, int, long, String などのデータ型について、キーと値のペアを読み書きできるAPI。キーと値のペアは内部ストレージにxmlファイルとして保存される。初回アクセス以降はメモリ上に展開されたキャッシュからデータを取得するため、高速にアクセスできる。

API名「SharedPreferences」から誤解されることもあるが、厳密には「ユーザー設定」を保存するためのものではなく、ユーザーのハイスコアなどの単純なデータを保存する際に使われる。たとえば、下記のコードは、リソース文字列 R.string.preference_file_key で識別される共有環境設定ファイルにアクセスして、プライベート モードで開きます。これにより、この共有環境設定ファイルにアクセスできるのは、このアプリだけになります。共有環境設定ファイルに名前を付ける場合、対象アプリを一意に識別できる名前を使用してください。簡単な方法としては、アプリ ID をプレフィックスとしてファイル名の先頭に付ける方法があります。
例: "jp.aoyama.a00001.xxmainactivity.PREFERENCE_FILE_KEY"


	Context context = getActivity();
	SharedPreferences sharedPref = context.getSharedPreferences(
					getString(R.string.preference_file_key), 
					Context.MODE_PRIVATE);

あるいは、アクティビティに対して共有環境設定ファイルが 1 つだけ必要な場合は、getPreferences() メソッドを使用します。


	SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);

共有環境設定ファイルへの書き込み。


	String user_name_value = ((EditText)findViewById(R.id.editTextName)).getText().toString());
	SharedPreferences.Editor editor = sharedPref.edit();
	editor.putString(getString(R.string.user_name_key), user_name_value);
	editor.commit();

共有環境設定ファイルから読み取る


    String user_name = sharedPref.getString(getString(R.string.user_name_key), DEFAULT_VALUE);

AndroidStudio の Device File Explorer からxmlファイルが実際に保存されていることが確認できる
「SharedPreferences」ファイルは、アプリのパッケージ内、Device File Explorer > data > data > xxmainactivity 、の「shared_prefs」フォルダ内にある。
つまり、アプリからしかアクセスできない内部ストレージ。