Preferensi Daftar Android: memiliki ringkasan sebagai nilai yang dipilih?

112

Saya memiliki aktivitas Preferensi yang menggunakan Preferensi Daftar sebagaimana ditentukan oleh file XML saya. Bagaimana cara mengatur ringkasan aktivitas daftar ke nilai yang dipilih?

Terima kasih!

Fran Fitzpatrick
sumber

Jawaban:

410

Cara termudah untuk melakukannya adalah dengan meminta Android melakukannya untuk Anda. Dengan asumsi Anda ingin ringkasan cocok dengan nilai yang dipilih, Anda cukup menyetel ringkasan ListPreferenceke"%s" menggunakan XML atau setSummarymetode di Java. Sebagai contoh:

<ListPreference
    android:key="pref_list"
    android:title="A list of preferences"
    android:summary="%s"
    android:entries="@array/pref_list_entries"
    android:entryValues="@array/pref_list_entries_values"
    android:defaultValue="0" />

Android akan mengganti %sdengan nilai string preferensi saat ini, seperti yang ditampilkan oleh alat ListPreferencepilih. Ringkasan daftar juga akan disetel dengan benar saat Anda memasukkan aktivitas — Anda tidak perlu menulis kode khusus apa pun untuk menyiapkannya pada awalnya.

Ini juga berfungsi dengan AndroidX ListPreference.

Aku menghabiskan jauh terlalu banyak waktu mucking dengan SharedPreferencespendengar sebelum saya menemukan ini.

George Hilliard
sumber
1
Aku tahu! Saya suka solusi elegan itu. Begitu sederhana, namun sulit ditemukan;)
jelas
7
Saya harus menggabungkan pembaruan manual dengan kecerdasan ini ... karena ringkasan tidak diperbarui ketika nilai diubah ...
Renetik
4
Jawaban yang sangat bagus. Percaya atau tidak, tetapi ini sebenarnya didokumentasikan: developer.android.com/reference/android/preference/…
Lior
1
Bisakah Anda mengonfirmasi, bahwa Anda memerlukan API> = 11 untuk "%s"? Dalam pengujian saya, "%s"tidak berfungsi dengan Gingerbread dan versi sebelumnya.
andreas1724
1
@BaptisteCandellier terima kasih atas perhatiannya. Jika ada sesuatu, tim Android akan menghentikannya. Saya telah menambahkan tautan ke androidx.
George Hilliard
29

Anda dapat menggunakan OnPreferenceChangeListeneruntuk mengubah ringkasan secara dinamis. Masalahnya adalah ia mendapatkan nilai yang dipilih (dari android:entryValues), bukan caption ( android:entries). Dalam kode berikut saya gunakan toString(), tetapi solusi yang tepat adalah menemukan judul untuk nilainya. Bagaimanapun, idenya berhasil:

public class Preferences extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.your_prefs);

        ListPreference listPreference = (ListPreference) findPreference("preference_key");
        if(listPreference.getValue()==null) {
            // to ensure we don't get a null value
            // set first value by default
            listPreference.setValueIndex(0);
        }
        listPreference.setSummary(listPreference.getValue().toString());
        listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                preference.setSummary(newValue.toString());
                return true;
            }
        });
    }
}
Axel
sumber
18

Saya juga ingin mencapai sesuatu yang serupa, tetapi masalah dengan https://stackoverflow.com/a/8155029/592025 adalah, ini menunjukkan nilai untuk preferensi saya (seperti 1, 2 3 dll). Saya ingin menunjukkan entri (string yang dapat dibaca manusia) sesuai dengan nilai yang dipilih.

Jadi saya mengubahnya dengan cara ini dan bekerja sesuai kebutuhan saya.

listPreference.setSummary(servicePreference.getEntry().toString());
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            // Set the value as the new value
            listPreference.setValue(newValue.toString());
            // Get the entry which corresponds to the current value and set as summary
            preference.setSummary(listPreference.getEntry());
            return false;
        }
    });

Triknya adalah dengan menggunakan getEntry()alih-alih getValue()dan setelah nilainya diubah, untuk menyetel nilai secara eksplisit dan membaca kembali entri tersebut.

midhunhk.dll
sumber
8

Saya pikir apa yang Anda cari jauh lebih sederhana dari yang Anda pikirkan, tambahkan baris kode berikut ke Preferenceitem Anda :

android:summary="%1$s"

Jadi akan terlihat seperti ini:

<ListPreference
            android:key="@string/pref_temp_key"
            android:title="@string/pref_temp_title"
            android:dialogTitle="@string/pref_temp_dialog_title"
            android:entries="@array/pref_tempUnit_entries"
            android:entryValues="@array/pref_tempUnit_entries"
            android:summary="%1$s"
            android:defaultValue="@string/pref_temp_default_value" />
42Geek
sumber
4

Pertama, dapatkan referensi ke ListPreference di onCreate Anda. Anda dapat menggunakan findPreference (). Sebagai contoh:

ListPreference pref = (ListPreference) findPreference("thePreferencesKey");

Kemudian, saat Anda pertama kali memuat Aktivitas dan setiap kali nilai preferensi berubah, gunakan metode apa pun yang Anda inginkan untuk mendapatkan nilai ListPreference dan setel ringkasannya dengan:

pref.setSummary(theNewString);
cottonBallPaws
sumber
2

Ini adalah kode yang saya gunakan, tidak memanggil setValue secara manual, karena saya yakin ini sudah dilakukan di tahap selanjutnya.

Berikut ini contohnya:

@Override
public boolean onPreferenceChange(Preference preference, Object value)
{
    String textValue = value.toString();

    ListPreference listPreference = (ListPreference) preference;
    int index = listPreference.findIndexOfValue(textValue);

    CharSequence[] entries = listPreference.getEntries();

    preference.setSummary(
                index >= 0
                        ? entries[index]
                        : null);

    return true;
}
Moberg
sumber
0

Inilah yang saya lakukan dan berhasil dengan baik. Di onSharedPreferenceChangeListener saya hanya memeriksa kunci dari apa yang diubah dan kemudian untuk ListPreferences mengubahnya kembali ke Human readable (entri bukan entryValue) dengan pernyataan if. Cukup mudah.

public class MyPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener{

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
    context = getActivity();

    if (context == null){
        Log.e("error","context is null");
    }

    prefs = PreferenceManager.getDefaultSharedPreferences(context);
    myFrequencyList = (Preference)  findPreference("frequency_key");
    prefs.registerOnSharedPreferenceChangeListener(this);

}


@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {

        if(key.equals("frequency_key")){
                String freq = sharedPreferences.getString("frequency_key", "8k Hz");
                if(freq.equals("8000")){
                    freq = "8k Hz";
                }
                else if(freq.equals("16000")){
                    freq = "16k Hz";
                }
                else if(freq.equals("22050")){
                    freq = "22.05k Hz";
                }
                else if(freq.equals("44100")){
                    freq = "44.1k Hz";
                }
                else if(freq.equals("48000")){
                    freq = "48k Hz";
                }
                else{
                    freq = "8k Hz";
                }
                myFrequencyList.setSummary(freq);
        }

tata letak xml

 <ListPreference android:id="@+id/frequency_list"
        android:key="frequency_key"
        android:summary="8000"
        android:title="Sample Rate"
        android:defaultValue="8000"
        android:dialogTitle="Larger sample rates create better sound quality but larger file sizes."
        android:entries="@array/freq_titles"
        android:entryValues="@array/freq_values"
        />

larik xml

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

<string-array name="freq_titles">
    <item>48k Hz</item>
    <item>44.1k Hz</item>
    <item>22.05k Hz</item>
    <item>16k Hz</item>
    <item>8k Hz</item>
</string-array>

<string-array name="freq_values">
    <item>48000</item>
    <item>44100</item>
    <item>22050</item>
    <item>16000</item>
    <item>8000</item>
</string-array>

Jordan Hochstetler
sumber
1
Idealnya, Anda membaca ringkasan secara dinamis sehingga Anda tidak perlu mengingatnya di dua tempat.
George Hilliard
0

Berikut adalah versi yang diperluas dari jawaban midhunhk yang membahas string "android: summary" yang bermanfaat juga

        // Retrieve & populate flash modes
        List<String> flashmodes = params.getSupportedFlashModes();
        if (flashmodes != null) {
            final ListPreference lp = (ListPreference) findPreference("flash_list");
            final String lp_basesummary = "Set the Flash mode. The default is 'auto'";

            lp.setEntries(flashmodes.toArray(new CharSequence[flashmodes.size()]));
            lp.setEntryValues(flashmodes.toArray(new CharSequence[flashmodes.size()]));
            // If there's only one option, make it the default
            if (flashmodes.size() == 1)
                lp.setValueIndex(0);

            lp.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");

            lp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    // Set the value as the new value
                    lp.setValue(newValue.toString());
                    // Get the entry which corresponds to the current value
                    // and set as summary
                    preference.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
                    return false;
                }
            });
        } else {
            // Remove the preference
            ((PreferenceGroup) findPreference("camera_preference")).removePreference(findPreference("flash_list"));
        }

        // Retrieve & populate focus modes
        List<String> focusmodes = params.getSupportedFocusModes();
        if (focusmodes != null) {
            final ListPreference lp = (ListPreference) findPreference("focus_mode_list");
            final String lp_basesummary = "Set the Focus mode. The default is 'auto'";
...

Dan, untuk memperjelas, android: summary dihapus dari xml terkait.

RudyF
sumber
0

Dan inilah salah satu cara untuk menangani pembaruan ringkasan preferensi Nada Dering mengikuti pilihan pengguna.

    final SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    final RingtonePreference rp_shuttle = (RingtonePreference) findPreference("shuttle_tone");
    rp_shuttle.setSummary(RingtoneManager
            .getRingtone(getApplicationContext(), Uri.parse(preference.getString("shuttle_tone", "DEFAULT_SOUND")))
            .getTitle(this));

    rp_shuttle.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        public boolean onPreferenceChange(Preference mypreference, Object newValue) {
            rp_shuttle.setSummary(RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(newValue + ""))
                    .getTitle(getApplicationContext()));

            return true;
        }
    })
RudyF
sumber
0

Anda memiliki metode bindPreferenceSummaryToValue di PreferenceActivity,

Anda dapat dengan mudah menambahkan ringkasan ke daftar dengan melakukan seperti ini:

private static void bindPreferenceSummaryToValue(Preference preference) {
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
            PreferenceManager
                    .getDefaultSharedPreferences(preference.getContext())
                    .getString(preference.getKey(), ""));
}

Pada metode OnCreate Anda memanggil fungsi bind seperti ini:

bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_OF_THE_LIST)));

Anda dapat dengan mudah menambahkan ringkasan orang lain dengan cara yang sama:

bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_1)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_2)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_3)));
Marcio Montenegro
sumber
0

di bawah onCreatePreferences lakukan ini ::

SharedPreferences sharedPreferences =getPreferenceScreen().getSharedPreferences();
PreferenceScreen prefScreen = getPreferenceScreen();
int count = prefScreen.getPreferenceCount();

for (int i = 0; i < count; i++) {
  Preference p = prefScreen.getPreference(i);
    if (p instanceof ListPreference) {
       String value = sharedPreferences.getString(p.getKey(), "");
       ListPreference listPreference = (ListPreference) preference;
       int prefIndex = listPreference.findIndexOfValue(stringValue);
       if (prefIndex >= 0) {
            preference.setSummary(listPreference.getEntries()[prefIndex]);
      }
    }
 }  
Derrick Njeru
sumber