[Android] フォームの標準ウィジェット(2) 静的な選択関連 - 数値の指定 ================================================================================ ※ 前回、記事サイズの関係で紹介できなかったシークバーとレーティングバーについて紹介する。 選択する以下の ウィジェット(Widget)とそのイベント処理。 ・ボタン(前回紹介) ・チェックボックス(前回紹介) ・トグルボタン(前回紹介) ・ラジオボタン(前回紹介) ・スピナー(前回紹介) ・シークバー ・レーティングバー 上記のウィジェットは、それぞれつぎのクラスを使う。また、そのときに使われるリス ナー・インターフェースも示す。 ------------------ -------------- ---------------------------------------------- ウィジェット クラス リスナー・インターフェース ------------------ -------------- ---------------------------------------------- ボタン Button View.OnClickListener, View.OnLongClickListener View.OnTouchListener チェックボックス CheckBox CompoundButton.OnCheckedChangeListener View.OnClickListener, View.OnLongClickListener View.OnTouchListener トグルボタン ToggleButton CompoundButton.OnCheckedChangeListener View.OnClickListener, View.OnLongClickListener View.OnTouchListener ラジオボタン RadioGroup RadioGroup.OnCheckedChangeListener RadioButton スピナー Spinner AdapterView.OnItemSelectedListener View.OnTouchListener シークバー SeekBar SeekBar.OnSeekBarChangeListener View.OnTouchListener レーティングバー RatingBar RatingBar.OnRatingBarChangeListener View.OnTouchListener ------------------ -------------- ---------------------------------------------- このサンプルは、アプリケーションの起動時に選択する値が決まっているパターンを示す。 ▲ レイアウト □ res/layout/main.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- (7) シークバー --> <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" /> <!-- (8) レーティングバー --> <RatingBar android:id="@+id/ratingBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:rating="2.5" /> </LinearLayout> --- (7) シークバー シークバーは、バー(スライダー)を指でタッチして、伸ばしたり縮めたりして、数値を設 定するウィジェット。EditText と違い、一定の範囲内で数値を設定できる。 <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" /> android:max 最大値 android:progress 初期状態での設定値 (8) レーティングバー シークバーの一種で、5 段階評価のような感じの指定ができる。 <RatingBar android:id="@+id/ratingBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:rating="2.5" /> android:rating 初期状態での設定値 ▲リソース値 □ res/values/strings.xml ※ 前回と同じ ▲ アクティビティ 単に、Widget にあわせたリスナーを割り当てているだけである。 なお、リスナーはインナー・クラスを使っている。 どのハンドラーが使われたかは、トーストとログで表示している。 □ FormWidgets01Activity.java package jp.marunomarun.android.formwidgets; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RatingBar; import android.widget.SeekBar; import android.widget.Spinner; import android.widget.Toast; import android.widget.ToggleButton; public class FormWidgets01Activity extends Activity { private static final int TOAST_DURATION = Toast.LENGTH_SHORT; private Context context; // (1) /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); context = this; // (2) OnCheckAndLongClickListener clickListener = new OnCheckAndLongClickListener(); OnTouchListener touchListener = new OnTouchListener(); // シークバー SeekBar seekBar1 = (SeekBar) findViewById(R.id.seekBar1); seekBar1.setOnSeekBarChangeListener(new OnSeekBarListener()); seekBar1.setOnClickListener(clickListener); // 動かないだけ seekBar1.setOnLongClickListener(clickListener); // 動かないだけ seekBar1.setOnTouchListener(touchListener); // レーティングバー RatingBar raitingBar1 = (RatingBar) findViewById(R.id.ratingBar1); raitingBar1.setOnRatingBarChangeListener(new OnRatingBarListener()); raitingBar1.setOnClickListener(clickListener); // 動かないだけ raitingBar1.setOnLongClickListener(clickListener); // 動かないだけ raitingBar1.setOnTouchListener(touchListener); } /** * ボタンのクリック、長クリックに対するリスナー * * @author marunomaruno */ private class OnCheckAndLongClickListener implements View.OnClickListener, View.OnLongClickListener { @Override public void onClick(View v) { String message = String.format( "OnClickListener.onClick() view: %s", v.getTag()); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); } @Override public boolean onLongClick(View v) { String message = String.format( "OnLongClickListener.onLongClick() view: %s", v.getTag()); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); return false; } } /** * タッチに対するリスナー * * @author marunomaruno */ private class OnTouchListener implements View.OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { String message = String.format( "OnTouchListener.onTouch() view: %s, event: %s", v.getTag(), event); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); return false; } } /** * シークバーの変更に対するリスナー * * @author marunomaruno */ private class OnSeekBarListener implements SeekBar.OnSeekBarChangeListener { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { String message = String .format("OnSeekBarChangeListener.onProgressChanged() view: %s, value: %d, fromUser: %b", seekBar.getTag(), progress, fromUser); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { String message = String .format("OnSeekBarChangeListener.onStartTrackingTouch() view: %s, value: %d", seekBar.getTag(), seekBar.getProgress()); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { String message = String .format("OnSeekBarChangeListener.onStopTrackingTouch() view: %s, value: %d", seekBar.getTag(), seekBar.getProgress()); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); } } /** * レーティング・バーの変更に対するリスナー * * @author marunomaruno */ private class OnRatingBarListener implements RatingBar.OnRatingBarChangeListener { @Override public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { String message = String.format( "RatingBar onRatingChanged() rate: %f, fromUser: %b", rating, fromUser); System.out.println(message); Toast.makeText(context, message, TOAST_DURATION).show(); } } } --- (1)(2) コンテキスト・オブジェクト 内部クラスでトーストを使っているので、このアクティビティ自身(this オブジェクト) を持っていたほうが都合がよい。 private Context context; // (1) context = this; // (2) (●) シークバー シークバーは、バー(スライダー)を指でタッチして、伸ばしたり縮めたりして、数値を設 定するウィジェット。EditText と違い、一定の範囲内で数値を設定できる。 SeekBar seekBar1 = (SeekBar) findViewById(R.id.seekBar1); seekBar1.setOnSeekBarChangeListener(new OnSeekBarListener()); seekBar1.setOnClickListener(clickListener); // 動かないだけ seekBar1.setOnLongClickListener(clickListener); // 動かないだけ seekBar1.setOnTouchListener(touchListener); なお、setOnClickListener()、setOnTouchListener() を指定しても動かない。 クリック時の動き まとめると、ACTION_DOWN > onStartTrackingTouch > onProgressChanged > ACTION_UP > onStopTrackingTouch --- OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c41208 action=0 ...} OnSeekBarChangeListener.onStartTrackingTouch() view: SeekBar, value: 50 OnSeekBarChangeListener.onProgressChanged() view: SeekBar, value: 86, fromUser: true OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c41208 action=1 ...} OnSeekBarChangeListener.onStopTrackingTouch() view: SeekBar, value: 86 --- 長押し時の動き まとめると、ACTION_DOWN > onStartTrackingTouch > ACTION_MOVE > onProgressChanged > ACTION_UP > onStopTrackingTouch --- OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c1fb60 action=0 ...} OnSeekBarChangeListener.onStartTrackingTouch() view: SeekBar, value: 50 OnSeekBarChangeListener.onProgressChanged() view: SeekBar, value: 80, fromUser: true OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c1fb60 action=2 ...} OnSeekBarChangeListener.onProgressChanged() view: SeekBar, value: 79, fromUser: true OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c1fb60 action=2 ...} OnTouchListener.onTouch() view: SeekBar, event: MotionEvent{46c1fb60 action=1 ...} OnSeekBarChangeListener.onStopTrackingTouch() view: SeekBar, value: 79 --- △ SeekBar クラス java.lang.Object + android.view.View + android.widget.ProgressBar + android.widget.AbsSeekBar + android.widget.SeekBar シークバーを管理するクラス。 setMax() で最大値を指定しなければ、0 ~ 100 の範囲での指定になる。 ・メソッド --- void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener l) synchronized void setMax(int max) synchronized int getProgress() synchronized void setProgress(int progress) --- △ SeekBar.OnSeekBarChangeListener インターフェース android.widget.SeekBar.OnSeekBarChangeListener ・メソッド --- abstract void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) abstract void onStartTrackingTouch(SeekBar seekBar) abstract void onStopTrackingTouch(SeekBar seekBar) --- (●) レーティングバー シークバーの一種で、5 段階評価のような感じの指定ができる。 RatingBar raitingBar1 = (RatingBar) findViewById(R.id.ratingBar1); raitingBar1.setOnRatingBarChangeListener(new OnRatingBarListener()); raitingBar1.setOnClickListener(clickListener); // 動かないだけ raitingBar1.setOnLongClickListener(clickListener); // 動かないだけ raitingBar1.setOnTouchListener(touchListener); クック時の動き まとめると、ACTION_DOWN > ACTION_UP > onRatingChanged --- OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c41208 action=0 ...} OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c1fc70 action=1 ...} RatingBar onRatingChanged() rate: 5.000000, fromUser: true --- 長押し時の動き まとめると、ACTION_DOWN > ACTION_MOVE > ACTION_UP > onClick --- OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c1fb60 action=0 ...] OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c1fb60 action=2 ...} OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c1fb60 action=2 ...] OnTouchListener.onTouch() view: RatingBar, event: MotionEvent{46c20bd0 action=1 ...] RatingBar onRatingChanged() rate: 1.000000, fromUser: true --- △ RatingBar クラス java.lang.Object + android.view.View + android.widget.ProgressBar + android.widget.AbsSeekBar + android.widget.RatingBar レーティング・バーを管理するクラス。 ・主なメソッド --- int getNumStars() float getRating() float getStepSize() boolean isIndicator() void setIsIndicator(boolean isIndicator) synchronized void setMax(int max) void setNumStars(int numStars) void setOnRatingBarChangeListener(RatingBar.OnRatingBarChangeListener listener) void setRating(float rating) void setStepSize(float stepSize) --- △ RatingBar.OnRatingBarChangeListener インターフェース android.widget.RatingBar.OnRatingBarChangeListener レーティング・バーが変化したときのリスナー・インターフェース。 ・メソッド --- abstract void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) --- 以上