2010-05-29 2 views
8

Я собираюсь создать активность настроек для своего приложения. Я определил PreferenceActivity с хорошим расположением, включая объект ListPreference, чтобы пользователь мог выбрать устройство Bluetooth. У меня возникли проблемы с динамическим заполнением списка.Можно ли загружать элементы ListPreference из адаптера?

Я хотел бы, чтобы заполнить ListPreference со значениями от адаптера массива (который я буду создавать и заполнять с соответствующими именами Bluetooth-устройства).

Если бы это был прядильный вид, я мог бы просто позвонить setAdapter(). Однако с объектом ListPreference я не могу понять, как подключить адаптер (findviewByID не будет отображаться из View To ListPreference, поэтому я даже не могу получить дескриптор объекта).

Я хотел бы подключить адаптер, а затем заполнить адаптер значениями, которые в свою очередь заполнили бы значениями ListPreference.

ответ

7

ListPreference не работает с адаптерами, он работает со строками. См setEntries() и setEntryValues()

Чтобы получить в вашем ListPreference, звоните findPreference() на вашем PreferenceActivity. Вставьте Preference, вы вернетесь в ListPreference.

+0

Nice, nice. Спасибо! –

10

Для особого случая списка устройств Bluetooth, вы можете использовать следующий класс:

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

} 

Он может участвовать непосредственно из вашего PREFS XML для хранения MAC как PREFS строки:

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

Прежде всего: спасибо вам за этот фрагмент кода. Он работает хорошо. но у меня проблема с рендерингом в предварительном просмотре в AS. 'Проблемы с отображением 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) [... и еще ... слишком много для этого символа предел здесь] ' – beta

4

Просто обновите это, если кто-то еще придет, ответ ge0rg работает, но немного изменил его, чтобы принять во внимание несколько предпочтений, а не только bluetooth, а также если у них нет каких-либо сопряженных устройств, dont получить ошибку с нулевым массивом.

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

`Надеюсь, что это поможет кому-то ... Ох, и это ставится под OnCreate метод для привилегированной активности

4

Другим способом было бы переопределить onPrepareDialogBuilder из ListPreference и инициализировать setSingleChoiceItems из AlertDialog.Builder непосредственно с адаптером:

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

Если вы посмотрите на Android источников, вы увидите, что onPrepareDialogBuilder() не называют:

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

с этими матрицами ввода. Для того, чтобы использовать некоторые ListPreference адаптер (например, ArrayAdaper, CursorAdapter), вам просто нужно позвонить:

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

вместо этого.

В этом случае ListPreference будет работать на адаптере напрямую, и вам не нужно будет копировать данные из адаптера, чтобы поместить их в массивы записей.

Найти рабочий образец here.

Смежные вопросы