2010-05-29 16 views
8

Je commence à créer une activité de paramètres pour mon application. J'ai défini un PreferenceActivity avec une mise en page sympa incluant un objet ListPreference pour que l'utilisateur puisse sélectionner un périphérique Bluetooth. J'ai des problèmes pour remplir dynamiquement la liste.Est-il possible de charger des éléments ListPreference à partir d'un adaptateur?

Je voudrais remplir ListPreference avec des valeurs d'un adaptateur de tableau (que je vais créer et alimenter avec des noms de périphériques Bluetooth pertinents).

Si c'était une vue de spinner, je pourrais simplement appeler setAdapter(). Cependant avec l'objet ListPreference je n'arrive pas à comprendre comment attacher un adaptateur (findviewByID ne sera pas converti de la vue à ListPreference, donc je ne peux même pas obtenir un handle pour l'objet).

Je voudrais joindre un adaptateur, puis remplir l'adaptateur avec des valeurs, ce qui à son tour peuplerait le ListPreference avec des valeurs.

Répondre

7

ListPreference ne fonctionne pas avec les cartes, cela fonctionne avec les chaînes. Voir setEntries() et setEntryValues()

Pour obtenir votre ListPreference, appelez findPreference() sur votre PreferenceActivity. Cast le Preference vous revenez à ListPreference.

+0

Nice, bien. Je vous remercie! –

10

Pour le cas particulier d'une liste des périphériques Bluetooth, vous pouvez utiliser la classe suivante:

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); 
    } 

} 

Il peut être impliqué directement à partir de votre XML prefs pour stocker le MAC comme une chaîne de prefs:

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

Tout d'abord: merci à tous pour ce morceau de code. Cela fonctionne bien. mais j'ai eu un problème de rendu dans l'aperçu dans AS. 'Problèmes de rendu java.lang.NullPointerException à de.jphjung.speedcamssiegerland.BluetoothDevicePreference. (BluetoothDevicePreference.java:20) à java.lang.reflect.Constructor.newInstance (Constructor.java:423) à android.preference.GenericInflater.createItem (GenericInflater.java:385) [... et quelques autres ... trop pour cette limite de caractères ici] – beta

4

Juste une mise à jour au cas où quelqu'un d'autre vient, réponse ge0rg fonctionne mais a changé un peu pour prendre en considération des préférences multiples et pas seulement le bluetooth et aussi si elles n'ont pas de dispositifs jumelés mis en place de sorte que vous N'obtenez pas d'erreur avec un tableau nul.

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); 

`Espérons que cela aide quelqu'un ... oh et ceci est mis sous la méthode onCreate pour l'activité de préférence

4

Une autre façon serait de passer outre onPrepareDialogBuilder de ListPreference et d'initialiser directement setSingleChoiceItems de AlertDialog.Builder avec votre adaptateur:

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); 
    } 
} 

Si vous regardez les sources Android, vous constaterez que onPrepareDialogBuilder() n'appelle:

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

avec ces tableaux d'entrée. Pour ListPreference utiliser une carte (par exemple ArrayAdaper, CursorAdapter), il vous suffit d'appeler:

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

à la place. De cette façon, ListPreference fonctionne directement sur l'adaptateur et vous n'avez pas besoin de copier les données de l'adaptateur pour les placer dans les tableaux d'entrées.

Trouver un échantillon de travail here.