X

シークバーの使い方 / Getting Started


シークバーはツマミをマウスで左右にドラッグしてパラメータを調整するGUI部品です。
オーディオのボリュームコントロール、パラメータの調整など、量的なパラメータを設定する場合に重宝します。
シークバーは、表示や動作にいくつかバリエーションが存在します。

  • 標準的なシークバー
  • 2つの設定値を同時に表示できるセカンダリ値を持ったシークバー
  • XMLをつかった独自レイアウトのシークバー

これらのシークバーは同じように実装することが可能です。この記事の中で順番に解説します。まずは大事なポイントから。

SeekBarを使う際の大事なポイント

ポイント 説明
SeekBarの初期値 SeekBar.setProgress()
レイアウト指定(android:progress)
SeekBarの上限 SeekBar.setMax()
レイアウト指定(android:max)


機能面のポイントは以下の通りです。

SeekBarを使う際に大事なメソッド・レイアウト

メソッド・インターフェイス 説明
SeekBar.setOnSeekBarChangeListenerインターフェイス シークバー変更時に呼び出されるOnSeekBarChangeListenerクラスを登録
OnSeekBarChangeListenerクラスonProgressChanged() ツマミの位置が変化した
OnSeekBarChangeListenerクラスonStartTrackingTouch() ツマミのドラッグを開始した
OnSeekBarChangeListenerクラスonStopTrackingTouch() ツマミのドラッグを終了した

ソースコード、サンプルなど詳細は続きからどうぞ。

まずはじめにレイアウトファイルを定義します
■layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="標準的なシークバー"
    />
<TextView android:id="@+id/TextView00"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="設定値表示"
    />
<SeekBar android:layout_height="wrap_content" android:id="@+id/SeekBar00"
	android:layout_width="match_parent"
	android:progress="25"
	android:max="100">
</SeekBar>
...省略...
</LinearLayout>

シークバーの設定値を表示するTextViewとSeekBar本体を定義しています。
16行目から19行目にかけてSeekBarのプロパティにはandroid:progressで初期値を、android:maxで上限値を設定しています。

続いて、処理するソースコードをみていきましょう。
■src/SeekBarActivity.java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final SeekBar sb0 = (SeekBar)findViewById(R.id.SeekBar00);
        final TextView tv0 = (TextView)findViewById(R.id.TextView00);

        // シークバーの初期値をTextViewに表示
        tv0.setText("設定値:"+sb0.getProgress());

        sb0.setOnSeekBarChangeListener(
                new OnSeekBarChangeListener() {
                    public void onProgressChanged(SeekBar seekBar,
                            int progress, boolean fromUser) {
                        // ツマミをドラッグしたときに呼ばれる
                    	tv0.setText("設定値:"+sb0.getProgress());
                    }

                    public void onStartTrackingTouch(SeekBar seekBar) {
                        // ツマミに触れたときに呼ばれる
                    }

                    public void onStopTrackingTouch(SeekBar seekBar) {
                        // ツマミを離したときに呼ばれる
                    }
                }
        );
 ...省略...
    }

SeekBarの各イベントはOnSeekBarChangeListenerと呼ばれるイベントリスナーが処理します。
上のソースコードでは14行目、20行目、24行目それぞれ、ツマミをドラッグしたとき、ツマミに触れたとき、ツマミを離したときをトリガに各種メソッドが呼び出されます。
今回の例ではツマミをドラッグしたときのonProgressChanged()メソッドでTextViewに現在のシークバーの設定値を表示する処理を実装しています。

セカンダリプログレスで前回の値を表示する

前回の設定値や、適応している有効値、デフォルトなど何らかの基準値を表したいときにはandroid:secondaryProgressが便利です。
サンプルでは、75として設定しています(main.xmlおよび下図)。
■layout/main.xml

...省略...
<SeekBar android:layout_height="wrap_content" android:id="@+id/SeekBar01"
	android:layout_width="match_parent"
	android:progress="50"
	android:secondaryProgress="75"
	android:max="100">
</SeekBar>
...省略...

ここでは、2番目のシークバーのセカンダリプログレスが一つ前の値を保持するように変更してみましょう。
■src/SeekBarActivity.java

...省略...
        sb.setOnSeekBarChangeListener(
                new OnSeekBarChangeListener() {
            		int oldValue;

                    public void onProgressChanged(SeekBar seekBar,
                            int progress, boolean fromUser) {
                        // ツマミをドラッグしたときに呼ばれる
                        tv.setText("設定値:"+sb.getProgress());
                        oldValue = sb.getProgress();
                    }

                    public void onStartTrackingTouch(SeekBar seekBar) {
                        // ツマミに触れたときに呼ばれる
                    }

                    public void onStopTrackingTouch(SeekBar seekBar) {
                        // ツマミを離したときに呼ばれる
                    	sb.setSecondaryProgress(oldValue);
                    }
                }
        );
...省略...

3行目、OnSeekBarChangeListenerクラス内で前回の値を保持(oldValue)しています。
10行目、つまみをドラッグしている最中はonProgressChanged()コールバックメソッドが呼び出されるため、oldValueに値を保持しておき、
19行目、つまみを離したときのonStopTrackingTouch()コールバックメソッドでoldValueを反映します。
保持、反映はそれぞれSeekBar.getProgress()メソッド、SeekBar.setProgress()メソッドを利用します。

レイアウトの変更

SeekBarの見た目を変更するにはレイアウトファイルを修正がもっともお手軽です。単純に背景を変えるだけであれば、
以下のxmlファイルの4行目のようにandroid:progressDrawableにdrawableを指定します。
■layout/main.xml

...省略...
<SeekBar android:layout_height="wrap_content" android:id="@+id/SeekBar02"
	android:layout_width="match_parent"
	android:progressDrawable="@drawable/seekbar_img"
	android:progress="75"
	android:max="100">
</SeekBar>
...省略...

しかし、これではつまみ以外の背景も、プログレス表示も両方が変わってしまい、現在設定値がわかりにくくなります。
そんなときは代わりに、レイアウトを指定しましょう。

カスタムレイアウトの適用

レイアウトを指定するといっても、やりかたは先ほどと一緒で、
android:progressDrawableにdrawableを指定します。
■layout/main.xml

...省略...
<SeekBar android:layout_height="wrap_content" android:id="@+id/SeekBar03"
	android:layout_width="match_parent"
	android:progress="50"
	android:secondaryProgress="75"
	android:max="100"
	android:progressDrawable="@drawable/myseekbar">
</SeekBar>
...省略...

7行目でmyseekbarを指定しています。myseekbarはxmlで構成されたDrawableで以下のような作りになっています。

■drawable/myseekbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/progress">
        <clip>
            <bitmap android:src="@drawable/seekbar_img"></bitmap>
        </clip>
    </item>
</layer-list>

3行目でprogressの内容を指定しています。今回はseekbar_imgを表示する設定です。直接画像を指定せずに、myseekbar.xmlなどXMLファイルを通じて作成すると、
柔軟性の高いレイアウトが作成できます。背景を変更したければ、itemを追加(android:id/background)すれば良いだけなので、とても簡単です。

以上、お疲れ様でした。

mhidaka: Software Engineerだよ。DroidKaigi Organizer / Androidと組込とRe:VIEW。techbooster主宰。mhidaka's writings http://booklog.jp/users/mhidaka 技術書典! http://techbookfest.org