Is it possible to load ListPreference items from an adapter?

对着背影说爱祢 提交于 2019-12-03 13:08:09

ListPreference doesn't work with adapters, it works with strings. See setEntries() and setEntryValues()

To get at your ListPreference, call findPreference() on your PreferenceActivity. Cast the Preference you get back to ListPreference.

For the special case of a list of bluetooth devices, you can use the following class:

package de.duenndns;

import android.bluetooth.*;
import android.content.Context;
import android.preference.ListPreference;
import android.util.AttributeSet;

import java.util.Set;

public class BluetoothDevicePreference extends ListPreference {

    public BluetoothDevicePreference(Context context, AttributeSet attrs) {
        super(context, attrs);

        BluetoothAdapter bta = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> pairedDevices = bta.getBondedDevices();
        CharSequence[] entries = new CharSequence[pairedDevices.size()];
        CharSequence[] entryValues = new CharSequence[pairedDevices.size()];
        int i = 0;
        for (BluetoothDevice dev : pairedDevices) {
            entries[i] = dev.getName();
            if (entries[i] == null) entries[i] = "unknown";
            entryValues[i] = dev.getAddress();
            i++;
        }
        setEntries(entries);
        setEntryValues(entryValues);
    }

    public BluetoothDevicePreference(Context context) {
        this(context, null);
    }

}

It can be involved directly from your prefs XML to store the MAC as a prefs string:

<de.duenndns.BluetoothDevicePreference
    android:key="bluetooth_mac"
    android:title="Bluetooth Device"
    android:dialogTitle="Choose Bluetooth Device" />

Just an Update to this in case someone else comes along, ge0rg answer works but changed it a little to take in consideration of multiple preferences and not just the bluetooth one and also if they dont have any paired devices set up so you dont get an error with a null array.

ListPreference BTList = (ListPreference) findPreference("your preference key");
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    CharSequence[] entries = new CharSequence[1];
    CharSequence[] entryValues = new CharSequence[1];
    entries[0] = "No Devices";
    entryValues[0] = "";
    if(pairedDevices.size() > 0){
        entries = new CharSequence[pairedDevices.size()];
        entryValues = new CharSequence[pairedDevices.size()];
        int i=0;
        for(BluetoothDevice device : pairedDevices){
            entries[i] = device.getName();
            entryValues[i] = device.getAddress();
            i++;
        }
    }
    BTList.setEntries(entries);
    BTList.setEntryValues(entryValues);

`Hope this helps someone...oh and this is put under the onCreate method for the preference activity

Another way would be to override onPrepareDialogBuilder of ListPreference and to initialize setSingleChoiceItems of AlertDialog.Builder directly with your adapter:

public class AdapterListPreference extends ListPreference
{
    @Override
    protected void onPrepareDialogBuilder( AlertDialog.Builder builder )
    {
        // don't call super.onPrepareDialogBuilder() because it'll check
        // for Entries and set up a setSingleChoiceItems() for them that
        // will never be used

        final ListAdapter adapter = …;

        builder.setSingleChoiceItems(
            adapter,
            0,
            new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick( DialogInterface dialog, int which )
                {
                    // adapter.getItemId( which )

                    dialog.dismiss();
                }
            } );

        builder.setPositiveButton( null, null );
    }
}

If you look at the Android sources, you'll find that onPrepareDialogBuilder() does call:

public AlertDialog.Builder setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener)

with those entry arrays. To make ListPreference use some adapter (e.g. ArrayAdaper, CursorAdapter), you just need to call:

public AlertDialog.Builder setSingleChoiceItems (ListAdapter adapter, int checkedItem, DialogInterface.OnClickListener listener)

instead.

This way ListPreference will operate on the adapter directly and you don't need to copy the data from the adapter to put them into the entries arrays.

Find a working sample here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!