Android, SeekBarPreference で設定した値を保存する

Android で CheckBoxPreference などを使って設定を行うと、リソースファイルの res/xml/settings.xml と PreferenceActivity を継承したクラスの定義をして addPreferenceFromResource メソッドで settings.xml の読み込みを行う程度で、簡単に設定の読み出し・保存ができる。

ところが、SeekBarPreference を使って設定をしてみようとするとシークバーのダイアログが表示されるが、設定の読み出し・保存はできなかった。
SeekBarPreference を使うには、設定の保存・読み出し処理を自分で書かなければいけないらしい。

以下は、Android のメニューボタンを押してメニューから設定画面を表示させ、シークバーダイアログを使って設定の読み出し・保存を行うコード。

res/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"
    android:layout_gravity="center"
    android:padding="25dip">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/about_seekbarsample" />
</LinearLayout>

res/menu/menu.xml (メニュー)

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/settings"
          android:title="@string/settings_label" />
</menu>

res/xml/settings.xml (設定のリソースファイル)

res/ws/serendip/seekbarsample/SeekBarPreference.java で定義した SeekBarPreference を使うために、ws.serendip.seekbarsample.SeekBarPreference と記述している。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
    <ws.serendip.seekbarsample.SeekBarPreference
        android:id="@+id/seekbar"
        android:key="seekbar"
        android:title="@string/seekbar_title"
        android:summary="@string/seekbar_summary" />
</PreferenceScreen>

res/values/strings.xml (文字列のリソースファイル)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="about_seekbarsample">This is SeekBarSample!\n\nClick menu button, to open SeekBar sample.</string>
    <string name="app_name">SeekBarSample</string>
    <string name="settings_label">Settings ...</string>
    <string name="settings_title">SeekBarSample settings</string>
    <string name="seekbar_title">SeekBar Setting</string>
    <string name="seekbar_summary">Settings by SeekBar.</string>
</resources>

src/ws/serendip/seekbarsample/SeekBarSample.java (アプリのメインコード)

メニューの作成とメニュー選択時の処理を行っている。

package ws.serendip.seekbarsample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class SeekBarSample extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.settings:
            startActivity(new Intent(this, Settings.class));
            return true;
        }
        return false;
    }
}

src/ws/serendip/seekbarsample/Settings.java (設定 Activity のコード)

Activity 生成時の設定の読み込み処理を行う。

package ws.serendip.seekbarsample;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Settings extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }
}

src/ws/serendip/seekbarsample/SeekBarPreference.java (SeekBarPreference のコード)

シークバーダイアログの生成処理や『OK』ボタンをクリックした際の設定保存処理などを行う。

シークバー操作時の処理は記述していないが、android.util.Log を使うと、LogCat で変化する値を確認することができる。

package ws.serendip.seekbarsample;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.DialogPreference;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.SeekBar;

public class SeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener {
    private SeekBar bar;
    private Context mContext;
    private static SharedPreferences sp;
    private static final String OPT_SEEKBAR_KEY = "seekbar";
    private static final int OPT_SEEKBAR_DEF = 30;
    private static final int LAYOUT_PADDING = 10;

    public SeekBarPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        sp = PreferenceManager.getDefaultSharedPreferences(context);
    }

    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        // TODO Auto-generated method stub
    }

    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub
    }

    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub
    }

    @Override
    protected View onCreateDialogView() {
        LinearLayout layout = new LinearLayout(mContext);
        layout.setPadding(LAYOUT_PADDING, LAYOUT_PADDING, LAYOUT_PADDING, LAYOUT_PADDING);
        bar = new SeekBar(mContext);
        bar.setOnSeekBarChangeListener(this);
        bar.setProgress(getValue());
        layout.addView(bar, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        return layout;
    }

    @Override
    protected void onBindDialogView(View v) {
        super.onBindDialogView(v);
    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            setValue(bar.getProgress());
        }
    }

    private void setValue(int value) {
        Editor ed = sp.edit();
        ed.putInt(OPT_SEEKBAR_KEY, value);
        ed.commit();
    }

    private int getValue() {
        return sp.getInt(OPT_SEEKBAR_KEY, OPT_SEEKBAR_DEF);
    }
}

忘れずに、AndroidManifest.xml に Settingsactivity を追加しておく。

<activity android:name=".Settings"
          android:label="@string/settings_title">
</activity>

以上のコードで SeekBarPreference を使って設定の読み出し・保存が可能となる。

Android SeekBarPreference Sample Screenshot

参考:诗意代码 – PoemCode » 设计自己的Android Preference
   Android(開発)/ちょっとした設定の永続化 – 俺の基地
   シークバー(SeekBar)を使用するには – 逆引きAndroid入門

初めてのAndroid
初めてのAndroid

posted with amazlet at 10.06.22
Ed Burnette
オライリージャパン
売り上げランキング: 35045
コメント

[…] Android, SeekBarPreference で設定した値を保存する : Serendip – Web … – … […]

開発初心者ですが、参考にさせて頂いています、ありがとうございます。

また、質問で申し訳ないのですが、SeekBarが2個ある場合はIDとKEYで識別するのかと思うのですが生成時にどこから取得したら良いのかという事とMAX値も生成時に渡したいと考えています。

お忙しいところ申し訳ないですが糸口になりそうな事でも教えて頂けると助かります。

コメント by Nick | 2010年9月2日 - 18:58

コメントありがとうございます。

最大値は setMax メソッドで設定できますよ。
レイアウトで定義する場合は android:max 属性で設定できます。

SeekBar は findViewById で ID 毎に取得できますよ。

コメント by iNo | 2010年9月3日 - 13:05

お返事ありがとうございます。

MAX値は、クラス生成時に動的に取得してonCreateDialogViewでsetMaxしました。

また、keyですがthis.getKey()にて取得出来ました。
IDも教えて頂いた通りやろうと思います。

ありがとうございました。

コメント by Nick | 2010年9月3日 - 13:38

参考にさせてもらっています。

SeekBarPreference内で画面の明るさを変更したい場合はどのようにしたらよいのでしょうか?
getWindow()が呼び出せればできるような事を調べていてわかったんですが、うまく言っていません。アドバイス頂けましたら幸いです。

コメント by sand | 2010年10月9日 - 21:50

> sand さま

コメントありがとうございます。

以下のURI先の記事の lp.screenBrightness = 1.0f の部分を SeekBarPreference で設定した値を代入するように変更すれば、画面の明るさを SeekBarPreference で設定した値に変更できます。

http://www.adakoda.com/android/000157.html

コメント by iNo | 2010年10月10日 - 14:53

ご返信ありがとうございます。
URLについてもありがとうございます。
実は、頂いたURLでは既に参考にしていたのですが、DialogPreference経由だからか、getWindow()をうまく呼び出せておりませんでした。

再度トライしてみます。
ありがとうございました。

コメント by sand | 2010年10月11日 - 20:16

> sandさま

SeekBarPreference から直接明るさを変えるのではなく、呼出し元の Activity が Resume する際に SharedPreferences を読み出して明るさを変えてみてはどうでしょうか。

コメント by iNo | 2010年10月12日 - 11:28

Androidでゲームを作る012…

テンプレートの変更とかに嵌ってしまったので、あまり進んでいないが、設定画面の実装を行っている。 タイトル画面の「SETTING」項目より起動します。 PreferenceActivityを使用しているので難しくない……

コメント by KENSINのブログ | 2011年2月12日 - 03:45

こんにちは、素人Androiderです。
このサイトで紹介されているものを作りたく、ダイアログをカスタムしたりいろいろ挑戦したのですが、途中このサイトを見つけ、無事完成させることができました。
とても感謝しております。ありがとうございます。
紹介内容の、ディレクトリの明記、ソースコードの明記、実行画像の掲載とも全て親切丁寧に説明されており、素人の私にでもわかりやすかったと思います。
苦戦した点として、勝手なミスではございますが
|<ws.serendip.seekbarsample.SeekBarPreference
をそのままコピーしてしまい実行エラーになってしまいました。
その後、説明文をよく読むとパッケージ名だと知り、修正すると、うまくいきました。
ありがとうございました。

話はそれますが、コメント欄が右揃えで他の方のコメントが若干読みづらかったです。(笑

コメント by 素人Androider | 2011年3月17日 - 11:01
コメント by SeekBar | プログラミング JAVA Android | 2013年7月5日 - 19:41

とても参考になりました。
画面の明るさを調整を実装したいのですが・・・
なかなかなりません(^▽^;)
「lp.screenBrightness = 1.0f の部分を SeekBarPreference で設定した値を代入」とありますがどうすればいいのでしょうか?
もしお手数でなければご教授ください。
(メールでもOKです)

コメント by so-04d | 2013年10月22日 - 18:15
Top