2010-05-29 12 views
8

Mam zamiar utworzyć działanie ustawień dla mojej aplikacji. Zdefiniowałem PreferenceActivity z ładnym układem obejmującym obiekt ListPreference dla użytkownika, aby wybrać urządzenie Bluetooth. Mam problem z dynamicznym zapełnianiem listy.Czy można załadować elementy ListPreference z adaptera?

Chciałbym wypełnić ListPreference wartościami z adaptera tablicowego (który utworzę i zapełnię odpowiednimi nazwami urządzeń Bluetooth).

Jeśli to był widok pokrętła, mógłbym zadzwonić pod numer setAdapter(). Jednak w przypadku obiektu ListPreference nie mogę dowiedzieć się, jak podłączyć adapter (nie będzie rzutowany z widoku do ListPreference, więc nie mogę nawet uzyskać dojścia do obiektu).

Chciałbym dołączyć adapter, a następnie zapełnić adapter wartościami, które z kolei wypełniłyby wartościami ListPreference.

Odpowiedz

10

Dla szczególnego przypadku listy urządzeń Bluetooth można stosować następujące klasy:

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

} 

może być związany bezpośrednio z prefs XML do przechowywania MAC jako ciąg prefs:

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

Po pierwsze: dziękuję wszystkim za ten fragment kodu. Działa dobrze. ale mam problem z renderowaniem w podglądzie w AS. 'Problemy z renderowaniem java.lang.NullPointerException at de.jphjung.speedcamssiegerland.BluetoothDevicePreference. (BluetoothDevicePreference.java:20) na java.lang.reflect.Constructor.newInstance (Constructor.java:423) at android.preference.GenericInflater.createItem (GenericInflater.java:385) [... i kilka innych ... za dużo dla tego limitu znaków tutaj] ' – beta

4

Po prostu aktualizacja do tego na wypadek pojawienia się kogoś innego, odpowiedź ge0rg działa, ale zmieniła trochę, aby wziąć pod uwagę wiele preferencji, a nie tylko bluetooth, a także jeśli nie mają skonfigurowanych żadnych sparowanych urządzeń, więc dont dostać błąd z tablicą zerową.

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

`Mam nadzieję, że to pomoże ktoś ... no i ten jest umieszczany metodą onCreate za aktywność preferencji

4

Innym sposobem byłoby zastąpić onPrepareDialogBuilder z ListPreference i zainicjować setSingleChoiceItems bezpośrednio z AlertDialog.Builder z adapterem:

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

Jeśli spojrzeć na źródłach Android, przekonasz się, że onPrepareDialogBuilder() ma zadzwonić:

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

z tymi tablicami wejściowymi. Aby użyć ListPreferencji za pomocą jakiegoś adaptera (np. ArrayAdaper, CursorAdapter), wystarczy wywołać:

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

zamiast tego.

W ten sposób ListPreferencja będzie działać bezpośrednio na adapterze i nie ma potrzeby kopiowania danych z adaptera w celu umieszczenia ich w tablicach wpisów.

Znajdź działającą próbkę here.

Powiązane problemy