LoginSignup
2
3

More than 5 years have passed since last update.

PreferenceFragment で RadioButton を実現する

Posted at

PreferenceFragment で RadioButton を実現する

Android の設定画面に表示した項目の一覧から項目を一つ選択したい。
例: アカウント一覧からアカウントを選択したい場合など。
PreferenceFragmentRadioButton.png

Android Framework の Preference 関連のクラスには RadioButton が用意されていないので下記の実装が必要になる。

雛形作成

Eclipse で Android 4.0.3(API Level: 15)以上を対象にした Android プロジェクトを新規作成する。
Android プロジェクトには、1つの PreferenceMainActivity の継承クラスと1つの PreferenceFragment の継承クラスが含まれる。

雛形 Eclipse プロジェクトは、下記の GitHub URL を参照のこと。

Account 一覧を表示

DB(にあると仮定する)からアカウント情報を読み込んで PreferenceFragment に追加する。
アカウント情報1件ごとに CheckBoxPreference のインスタンスを生成して親の PreferenceScreen に追加する。

    public class PreferenceAccountFragment extends PreferenceFragment {

        private PreferenceScreen mRootPreferenceScreen;

        private String mSelectAccount;

        @Override
        public void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mRootPreferenceScreen = getPreferenceManager().createPreferenceScreen(getActivity());
            setPreferenceScreen(mRootPreferenceScreen);
        }

        @Override
        public void onResume() {
            super.onResume();
            loadSelectAccount();
            removeAllPreferenceScreen();
            buildAccountsPreferences();
        }

        private void removeAllPreferenceScreen() {
            mRootPreferenceScreen.removeAll();
        }

        private void buildAccountsPreferences() {
            for (final String account : Constants.ACCOUNTS) {
                final Preference preference = buildAccountPreferences(account);
                mRootPreferenceScreen.addPreference(preference);
            }
        }

        private Preference buildAccountPreferences(final String account) {
            final CheckBoxPreference p = new CheckBoxPreference(getActivity());

            p.setTitle(account);

            final boolean isChecked = TextUtils.equals(mSelectAccount, account);
            p.setChecked(isChecked);

            return p;
        }

        private void loadSelectAccount() {
            mSelectAccount = getSelectAccount(getActivity());
        }

        private String getSelectAccount(final Context context) {
            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
            return prefs.getString(context.getString(R.string.pref_account_key), null);
        }

        private void setSelectAccount(final Context context, final String value) {
            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
            final Editor editor = prefs.edit();
            editor.putString(context.getString(R.string.pref_account_key), value);
            editor.commit();
        }
    }

RadioButton の機能を実装する

CheckBoxPreference そのままの機能では、複数の項目を選択できてしまう。
そこで、 RadioButton のように 1つの項目だけを選択するようにする。

    private Preference buildAccountPreferences(final String account) {
        final CheckBoxPreference p = new CheckBoxPreference(getActivity());

        ....

        // 下記の1行を追加
        p.setOnPreferenceChangeListener(mOnPreferenceChangeListener);
    }

    private final Preference.OnPreferenceChangeListener mOnPreferenceChangeListener =
        new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(final Preference preference, final Object newValue) {
                // true -> false ignore
                if (Boolean.FALSE.equals(newValue)) {
                    return false;
                }

                // save account
                final String account = String.valueOf(preference.getTitle());
                setSelectAccount(getActivity(), account);

                // refresh accounts preference screen
                loadSelectAccount();
                removeAllPreferenceScreen();
                buildAccountsPreferences();

                return true;
            }
        };

UI を CheckBox から RadioButton にする

CheckBox に RadioButton のリソースを適用する定義を作成する。

res/layout/preference_widget_checkbox.xml

    <?xml version="1.0" encoding="utf-8"?>
    <CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+android:id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:button="?android:attr/listChoiceIndicatorSingle"
        android:clickable="false"
        android:focusable="false" />

res/values/styles.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
        <style name="Preference" />
        <style name="Preference.CheckBoxPreference">
            <item name="android:widgetLayout">@layout/preference_widget_checkbox</item>
        </style>
    </resources>

res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
        <style name="Theme" parent="android:Theme.Holo">
            <item name="accountCheckBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
        </style>
    </resources>

res/values/attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- PreferenceAccountFragment accountCheckBoxPreferenceStyle -->
        <attr name="accountCheckBoxPreferenceStyle" format="reference" />
    </resources>

AndroidManifest.xml

    <activity
        android:name=".PreferenceMainActivity"
        android:label="@string/app_name"
        android:theme="@style/Theme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

CheckBoxPreference のコンストラクタで、作成した RadioButton のリソースを指定する。

    final CheckBoxPreference p = new CheckBoxPreference(getActivity(),
        null, R.attr.accountCheckBoxPreferenceStyle);

完成

完成したソースファイル一式は下記のGitHubにアップした。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3