How to create RadioButton group in preference.xml

2019-03-08 11:03发布

问题:

I'm beginner in Java Android developing. I'm using Eclipse SDK 3.6.1 version. I have a preferences window with two checkbox and one back button.

    <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
             <PreferenceCategory
             android:title="PIN requirement">                
            <CheckBoxPreference                        
                    android:title="Use PIN" 
                    android:defaultValue="true"                                              
                    android:key="checkboxPref" /> 
           <CheckBoxPreference
                    android:title="Don't use PIN"
                    android:defaultValue="false"                        
                    android:key="checkboxPref2" />

                    </PreferenceCategory>

<PreferenceCategory>
    <Preference
            android:title="Back"                
            android:key="customPref" />
    </PreferenceCategory>
</PreferenceScreen>

How to change two CheckBox in to the RadioButton group?

回答1:

If you need just to enable or disable using PIN, only one CheckBoxPreference will be enough in this case (see example code below, First Category). RadioButtons are usually used, when you need to choose something from a list of settings (ListPreference) - for example (see example code, Second Category), to pick a color.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="First Category">
        <CheckBoxPreference
            android:title="Using PIN"
            android:defaultValue="false"
            android:key="checkboxPref" 
            android:summaryOn="Disable PIN" 
            android:summaryOff="Enable PIN"/>
    </PreferenceCategory>

    <PreferenceCategory
        android:title="Second Category">
        <ListPreference
            android:title="Pick your favourite color"
            android:key="listPref"
            android:defaultValue="4"
            android:entries="@array/listArray"
            android:entryValues="@array/listValues" />
    </PreferenceCategory>
</PreferenceScreen>

The source code for this example will be:

public class PreferencesHelpExample extends PreferenceActivity implements OnSharedPreferenceChangeListener {

    public static final String KEY_LIST_PREFERENCE = "listPref";

    private ListPreference mListPreference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.preferences);

        // Get a reference to the preferences
        mListPreference = (ListPreference)getPreferenceScreen().findPreference(KEY_LIST_PREFERENCE);

    }

    @Override
    protected void onResume() {
        super.onResume();

        // Setup the initial values
        mListPreference.setSummary("Current value is " + mListPreference.getEntry().toString());

        // Set up a listener whenever a key changes            
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Unregister the listener whenever a key changes            
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);    
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        // Set new summary, when a preference value changes
        if (key.equals(KEY_LIST_PREFERENCE)) {
            mListPreference.setSummary("Current value is " + mListPreference.getEntry().toString()); 
        }
    }
}

For ListPreference you will also need an arrays.xml file, which is located in the "values" folder:

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <string-array name="listArray">
        <item>red</item>
        <item>orange</item>
        <item>yellow</item>
        <item>green</item>
        <item>blue</item>
        <item>violet</item>
    </string-array>

    <string-array name="listValues">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
        <item>6</item>
    </string-array>

</resources>

See also some great examples, working with PreferenceActivity - they helped me a lot:

Android Preferences;
How to create a group of RadioButtons instead of a list;
How to display the current value of an Android Preference in the Preference summary?



回答2:

In some situations, having Preferences behave as radio buttons is a nice feature e.g a simple way of including summary text under each option.

Making a group of checkboxes behave like a group of radio buttons is fairly simple. To do this in Preferences, register all the checkboxes in the group to the same OnPreferenceChangeListener then in this listener use findPreference() to find the other checkboxes and call setChecked(false);

public boolean onPreferenceChange(Preference preference, Object newValue) {
    String key = preference.getKey();
    if (key.equals("checkboxPref")) {
        //Reset other items
        CheckBoxPreference p = (CheckBoxPreference)findPreference("checkboxPref2");
        p.setChecked(false);
    }
    else if (key.equals("checkboxPref2")) {
        //Reset other items
        CheckBoxPreference p = (CheckBoxPreference)findPreference("checkboxPref");
        p.setChecked(false);
    }

    //Force the current focused checkbox to always stay checked when pressed
    //i.e confirms value when newValue is checked (true) and discards newValue
    //when newValue is unchecked (false)
    return (Boolean)newValue;
}

The only downside is that the checkboxes will not look like radio buttons...



回答3:

I think this is pretty simple if that is what you want:

  1. Add the checkboxes at the preferenses xml like that:

     <CheckBoxPreference
        android:key="prefkey_cbp_1"
        android:summary="@string/prefkey_cbp_1"
        android:title="@string/prefkey_cbp_1"
        android:defaultValue="false" />
    
    <CheckBoxPreference
        android:key="prefkey_cbp_2"
        android:summary="@string/prefkey_cbp_2"
        android:title="@string/prefkey_cbp_2"
        android:defaultValue="false" />
    
    //etc...
    
  2. At the preferences class onCreate build an CheckBoxPreference array or list or whatever you like, like that:

    ArrayList<CheckBoxPreference> cbp_list = new ArrayList<CheckBoxPreference>();
    cbp_list.add((CheckBoxPreference) getPreferenceManager()
            .findPreference(PreferencesProtocol.prefkey_cbp_1));
    cbp_list.add((CheckBoxPreference) getPreferenceManager()
            .findPreference(PreferencesProtocol.prefkey_cbp_2));
    
  3. Make your preferences class implement OnPreferenceClickListener and set the OnPreferenceClickListener to the checkboxes like that :

    for (CheckBoxPreference cbp : cbp_list) {
    cbp.setOnPreferenceClickListener(this);
    }
    
  4. Then just override the onPreferenceClick and handle any click. For example if you want checkboxes to perform like radio buttons (in the same radiogroup), meaning, only one checkbox at the time to be check, do something like that:

    @Override
    public boolean onPreferenceClick(Preference arg0) {
    
    for (CheckBoxPreference cbp : cbp_list) {
    
        if (!cbp.getKey().equals(arg0.getKey()) && cbp.isChecked()) {
            cbp.setChecked(false);
        }
    
    }
    
    return false;
    }
    


回答4:

try this:

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, @NonNull Preference preference) {
        CheckBoxPreference cb1 = null;
        CheckBoxPreference cb2 = null;
        ListAdapter adapter = preferenceScreen.getRootAdapter();
        for(int i = 0; i < preferenceScreen.getRootAdapter().getCount(); i++)
        {
            //attention to type and key
            Preference pref = (Preference) adapter.getItem(i);
            if (pref == null || pref.getKey() == null)
                continue;
            if (pref.getKey().equals(getString(R.string.tag_preference_key_always_zoom_to_akt_position)))
                cb1 = (CheckBoxPreference) pref;
            if (pref.getKey().equals(getString(R.string.tag_preference_key_always_zoom_to_last_location)))
                cb2 = (CheckBoxPreference) pref;
            if (cb1 != null && cb2 != null)
                break;
        }
        //be safe
        if (cb1 == null || cb2 == null)
            return super.onPreferenceTreeClick(preferenceScreen, preference);

        if (preference.getKey().equals(getString(R.string.tag_preference_key_always_zoom_to_akt_position))) {
            CheckBoxPreference cb = (CheckBoxPreference) preference;
            cb2.setChecked(!cb.isChecked());
        }
        if (preference.getKey().equals(getString(R.string.tag_preference_key_always_zoom_to_last_location))) {
            CheckBoxPreference cb = (CheckBoxPreference) preference;
            cb1.setChecked(!cb.isChecked());
        }
        return super.onPreferenceTreeClick(preferenceScreen, preference);
    }