it-swarm.com.de

Wie zeige ich den aktuellen Wert einer Android-Voreinstellung in der Voreinstellungsübersicht an?

Das muss sehr oft auftauchen.

Wenn der Benutzer Voreinstellungen in einer Android-App bearbeitet, möchte ich, dass er den aktuell eingestellten Wert der Voreinstellung in der Preference-Übersicht sehen kann.

Beispiel: Wenn ich eine Voreinstellung für "Alte Nachrichten verwerfen" eingestellt habe, die die Anzahl der Tage angibt, nach denen die Nachrichten bereinigt werden müssen. In der PreferenceActivity möchte ich den Benutzer sehen:

"Alte Nachrichten verwerfen" <- title

"Nachrichten nach x Tagen aufräumen" <- summary wobei x der aktuelle Voreinstellungswert ist 

Zusätzliches Guthaben: machen Sie es wiederverwendbar, sodass ich es problemlos auf alle meine Vorlieben anwenden kann, unabhängig von ihrem Typ (sodass es mit EditTextPreference, ListPreference usw. mit minimaler Codierung funktioniert).

433
nyenyec

Es gibt Möglichkeiten, dies zu einer allgemeineren Lösung zu machen, wenn dies Ihren Bedürfnissen entspricht.

Wenn Sie beispielsweise generell festlegen möchten, dass alle Listeneinstellungen als Zusammenfassung angezeigt werden, könnten Sie Folgendes für Ihre onSharedPreferenceChanged-Implementierung haben:

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    Preference pref = findPreference(key);

    if (pref instanceof ListPreference) {
        ListPreference listPref = (ListPreference) pref;
        pref.setSummary(listPref.getEntry());
    }
}

Dies ist leicht erweiterbar auf andere Präferenzklassen.

Durch die Verwendung der Funktionen getPreferenceCount und getPreference in PreferenceScreen und PreferenceCategory können Sie leicht eine generische Funktion schreiben, um durch den Einstellungsbaum zu navigieren und die Zusammenfassungen aller Präferenzen der gewünschten Typen auf ihre toString-Darstellung zu setzen

151
DozenCrows

Hier ist meine Lösung ... FWIW

package com.example.PrefTest;

import Android.content.SharedPreferences;
import Android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import Android.os.Bundle;
import Android.preference.EditTextPreference;
import Android.preference.ListPreference;
import Android.preference.Preference;
import Android.preference.PreferenceActivity;
import Android.preference.PreferenceGroup;
import Android.preference.PreferenceManager;

public class Preferences extends PreferenceActivity implements
        OnSharedPreferenceChangeListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager.setDefaultValues(Preferences.this, R.xml.preferences,
            false);
        initSummary(getPreferenceScreen());
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Set up a listener whenever a key changes
        getPreferenceScreen().getSharedPreferences()
                .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Unregister the listener whenever a key changes
        getPreferenceScreen().getSharedPreferences()
                .unregisterOnSharedPreferenceChangeListener(this);
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
            String key) {
        updatePrefSummary(findPreference(key));
    }

    private void initSummary(Preference p) {
        if (p instanceof PreferenceGroup) {
            PreferenceGroup pGrp = (PreferenceGroup) p;
            for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
                initSummary(pGrp.getPreference(i));
            }
        } else {
            updatePrefSummary(p);
        }
    }

    private void updatePrefSummary(Preference p) {
        if (p instanceof ListPreference) {
            ListPreference listPref = (ListPreference) p;
            p.setSummary(listPref.getEntry());
        }
        if (p instanceof EditTextPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            if (p.getTitle().toString().toLowerCase().contains("password"))
            {
                p.setSummary("******");
            } else {
                p.setSummary(editTextPref.getText());
            }
        }
        if (p instanceof MultiSelectListPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            p.setSummary(editTextPref.getText());
        }
    }
}
140
EddieB

Android Dokumentation sagt, dass man in getSummary() eine String-Formatierungsmarkierung verwenden kann:

Wenn die Zusammenfassung einen String-Formatierungsmarker enthält (d. H. "% S" oder "% 1 $ s"), wird der aktuelle Eingabewert an seiner Stelle ersetzt.

Die Angabe von Android:summary="Clean up messages after %s days" in der ListPreference-XML-Deklaration funktionierte für mich.

Hinweis: Dies funktioniert nur für ListPreference.

89
Robertas

Wenn Sie PreferenceFragment verwenden, habe ich es so gelöst. Es ist selbsterklärend.

public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      addPreferencesFromResource(R.xml.settings);
      getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onResume() {
      super.onResume();
      for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) {
        Preference preference = getPreferenceScreen().getPreference(i);
        if (preference instanceof PreferenceGroup) {
          PreferenceGroup preferenceGroup = (PreferenceGroup) preference;
          for (int j = 0; j < preferenceGroup.getPreferenceCount(); ++j) {
            Preference singlePref = preferenceGroup.getPreference(j);
            updatePreference(singlePref, singlePref.getKey());
          }
        } else {
          updatePreference(preference, preference.getKey());
        }
      }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
      updatePreference(findPreference(key), key);
    }

    private void updatePreference(Preference preference, String key) {
      if (preference == null) return;
      if (preference instanceof ListPreference) {
        ListPreference listPreference = (ListPreference) preference;
        listPreference.setSummary(listPreference.getEntry());
        return;
      }
      SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
      preference.setSummary(sharedPrefs.getString(key, "Default"));
    }
  }
79
tdevaux

Meine Option ist, ListPreference zu erweitern und es ist sauber:

public class ListPreferenceShowSummary extends ListPreference {

    private final static String TAG = ListPreferenceShowSummary.class.getName();

    public ListPreferenceShowSummary(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ListPreferenceShowSummary(Context context) {
        super(context);
        init();
    }

    private void init() {

        setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference arg0, Object arg1) {
                arg0.setSummary(getEntry());
                return true;
            }
        });
    }

    @Override
    public CharSequence getSummary() {
        return super.getEntry();
    }
}

Dann fügen Sie in Ihre Einstellungen.xml hinzu:

<yourpackage.ListPreferenceShowSummary
    Android:key="key" Android:title="title"
    Android:entries="@array/entries" Android:entryValues="@array/values"
    Android:defaultValue="first value"/>
32
Youyougoslave

Sie können die Standard-Voreinstellungsklassen überschreiben und die Funktion implementieren.

public class MyListPreference extends ListPreference  {
    public MyListPreference(Context context) { super(context); }
    public MyListPreference(Context context, AttributeSet attrs) { super(context, attrs); }
    @Override
    public void setValue(String value) {
        super.setValue(value);
        setSummary(getEntry());
    }
}

Später in Ihrem XML können Sie benutzerdefinierte Einstellungen wie verwenden 

<your.package.name.MyListPreference 
    Android:key="noteInterval"
    Android:defaultValue="60"
    Android:title="Notification Interval"
    Android:entries="@array/noteInterval"
    Android:entryValues="@array/noteIntervalValues"
    />
23
Palani

Nach einigen Stunden, in denen ich dieses Problem gelöst habe, habe ich diesen Code implementiert:

[UPDATE: die endgültige Version] 

public class MyPreferencesActivity extends PreferenceActivity {
    ...
    ListPreference m_updateList;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        m_updateList = (ListPreference) findPreference(getString(R.string.pref_update_interval_key));
        String currentValue = m_updateList.getValue();
        if (currentValue == null) {
            m_updateList.setValue((String)m_updateList.getEntryValues()[DEFAULT_UPDATE_TIME_INDEX]);
            currentValue = m_updateList.getValue();
        }
        updateListSummary(currentValue);    

        m_updateList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                updateListSummary(newValue.toString());
                return true;
            }       
        });     
    }

    private void updateListSummary(String newValue) {
        int index = m_updateList.findIndexOfValue(newValue);
        CharSequence entry = m_updateList.getEntries()[index];
        m_updateList.setSummary(entry);
    }
}

Das war die einzige Lösung, die für mich gut funktionierte. Vorher habe ich versucht, von ListPreferences eine Unterklasse zu erstellen und Android zu implementieren: summary = "bla bla bla% s". Weder funktionierte.

21
Subtle Fox

Vielleicht wie ListPreference: Ändern Sie getSummary, um das zu bekommen, was Sie möchten:

package your.package.preference;

import Android.content.Context;
import Android.util.AttributeSet;

public class EditTextPreference extends Android.preference.EditTextPreference{
        public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        public EditTextPreference(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public EditTextPreference(Context context) {
            super(context);
        }

        @Override
        public CharSequence getSummary() {
            if(super.getSummary() == null) return null;

            String summary = super.getSummary().toString();
            return String.format(summary, getText());
        }
    }

Und verwende das in deiner XML:

<your.package.EditTextPreference
                Android:key="pref_alpha"
                Android:summary="Actual value: %s"
                Android:title="Title"
                Android:defaultValue="default"
                />

Sie können also eine Zusammenfassung mit %s anstelle des tatsächlichen Werts schreiben.

18
Eruvanos

Dies ist der Code, den Sie benötigen, um die Zusammenfassung auf den ausgewählten Wert festzulegen. Es legt auch die Werte beim Start fest und beachtet die Standardwerte, nicht nur bei Änderungen. Ändern Sie einfach "R.layout.prefs" in Ihre XML-Datei und erweitern Sie die setSummary-Methode nach Ihren Bedürfnissen. Es behandelt eigentlich nur ListPreferences, ist aber leicht an andere Präferenzen anzupassen.

package de.koem.timetunnel;

import Android.content.SharedPreferences;
import Android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import Android.os.Bundle;
import Android.preference.ListPreference;
import Android.preference.Preference;
import Android.preference.PreferenceActivity;
import Android.preference.PreferenceGroup;

public class Prefs 
    extends PreferenceActivity 
    implements OnSharedPreferenceChangeListener {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       this.addPreferencesFromResource(R.layout.prefs);
       this.initSummaries(this.getPreferenceScreen());

       this.getPreferenceScreen().getSharedPreferences()
           .registerOnSharedPreferenceChangeListener(this);
    }

  /**
    * Set the summaries of all preferences
    */
  private void initSummaries(PreferenceGroup pg) {
      for (int i = 0; i < pg.getPreferenceCount(); ++i) {
          Preference p = pg.getPreference(i);
          if (p instanceof PreferenceGroup)
              this.initSummaries((PreferenceGroup) p); // recursion
          else
              this.setSummary(p);
      }
  }

  /**
    * Set the summaries of the given preference
    */
  private void setSummary(Preference pref) {
      // react on type or key
      if (pref instanceof ListPreference) {
          ListPreference listPref = (ListPreference) pref;
          pref.setSummary(listPref.getEntry());
      }
  }

  /**
    * used to change the summary of a preference
    */
  public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
     Preference pref = findPreference(key);
     this.setSummary(pref);
  }

  // private static final String LOGTAG = "Prefs";
}

koem

18
Koem

Tatsächlich kann CheckBoxPreference basierend auf dem Wert des Kontrollkästchens eine andere Zusammenfassung angeben. Siehe die Attribute Android: summaryOff und Android: summaryOn (sowie die entsprechenden CheckBoxPreference-Methoden).

11
dhaag23

Für EditTextPreference:

public class MyEditTextPreference extends EditTextPreference {
    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setText(String text) {
        super.setText(text);
        setSummary(text);
    }
}
11
lordmegamax

Wenn jemand noch nach Antworten auf diese Fragen sucht, sollten Sie thirtythreeforty s überprüfen.

<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 ersetzt% s durch den aktuellen Zeichenfolgenwert der Einstellung, wie er in der Auswahlfunktion von ListPreference angezeigt wird.

8
Irritator

Danke für diesen Tipp!

Ich habe einen Präferenzbildschirm und möchte den Wert für jede Listenpräferenz als Zusammenfassung anzeigen.

Das ist jetzt mein Weg:

public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
}

@Override
protected void onResume() {
    super.onResume();

    // Set up initial values for all list preferences
    Map<String, ?> sharedPreferencesMap = getPreferenceScreen().getSharedPreferences().getAll();
    Preference pref;
    ListPreference listPref;
    for (Map.Entry<String, ?> entry : sharedPreferencesMap.entrySet()) {
        pref = findPreference(entry.getKey());
        if (pref instanceof ListPreference) {
            listPref = (ListPreference) pref;
            pref.setSummary(listPref.getEntry());
        }
    }

    // Set up a listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
    super.onPause();

    // Unregister the listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);    
}

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    Preference pref = findPreference(key);

    if (pref instanceof ListPreference) {
        ListPreference listPref = (ListPreference) pref;
        pref.setSummary(listPref.getEntry());
    }
}

Das funktioniert für mich, aber ich frage mich, welche die beste Lösung (Leistung, Stabilität, Skalierbarkeit) ist: die eine, die Koem zeigt oder die hier?

7
alexx

Danke, Reto, für die ausführliche Erklärung!

Falls dies für jedermann hilfreich ist, musste ich den von Reto Meier vorgeschlagenen Code ändern, damit er mit dem SDK für Android 1.5 funktioniert

@Override
protected void onResume() {
    super.onResume();

    // Setup the initial values
    mListPreference.setSummary("Current value is " + mListPreference.getEntry().toString()); 

    // Set up a listener whenever a key changes            
    ...
}

Die gleiche Änderung gilt für die Rückruffunktion onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) 

Prost,

Chris

6
Chris

Ich habe gesehen, wie alle abgestimmten Antworten zeigen, wie die Zusammenfassung mit dem genauen aktuellen Wert festgelegt wird, aber das OP wollte auch etwas wie:

"Bereinigen Sie Nachrichten nach x Tagen" * <- summary Dabei ist x der aktuelle Voreinstellungswert 

Hier ist meine Antwort, um das zu erreichen

Wie Dokumentation sagt über ListPreference.getSummary():

Gibt die Zusammenfassung dieser ListPreference zurück. Wenn die Zusammenfassung einen String-Formatierungsmarker enthält (d. H. "% S" oder "% 1 $ s"), wird das aktuelle Der Eingabewert wird an seiner Stelle ersetzt.

Ich habe jedoch mehrere Geräte ausprobiert und es scheint nicht zu funktionieren. Mit einigen Recherchen fand ich eine gute Lösung in dieser Antwort . Es besteht einfach darin, jede Preference, die Sie verwenden, zu erweitern und getSummary() zu überschreiben, um wie in der Android-Dokumentation angegeben zu arbeiten.

4

Ich habe das Problem mit dem folgenden Nachkommen von ListPreference gelöst: 

public class EnumPreference extends ListPreference {

    public EnumPreference(Context aContext, AttributeSet attrs) {
        super(aContext,attrs);
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        setSummary(getEntry());
        return super.onCreateView(parent);
    }

    @Override
    protected boolean persistString(String aNewValue) {
        if (super.persistString(aNewValue)) {
            setSummary(getEntry());
            notifyChanged();
            return true;
        } else {
            return false;
        }
    }
}

Scheint in 1.6 bis 4.0.4 gut zu funktionieren.

4
public class ProfileManagement extends PreferenceActivity implements
OnPreferenceChangeListener {
    EditTextPreference screenName;
    ListPreference sex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.layout.profile_management);

            screenName = (EditTextPreference) findPreference("editTextPref");
            sex = (ListPreference) findPreference("sexSelector");

            screenName.setOnPreferenceChangeListener(this);
            sex.setOnPreferenceChangeListener(this);

    }   

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        preference.setSummary(newValue.toString());
        return true;
    }
}
4
GalkinAndrew

Hier ist meine Lösung:

Erstellen Sie eine Präferenztyp-Getter-Methode.

protected String getPreference(Preference x) {
    // http://stackoverflow.com/questions/3993982/how-to-check-type-of-variable-in-Java
    if (x instanceof CheckBoxPreference)
        return "CheckBoxPreference";
    else if (x instanceof EditTextPreference)
        return "EditTextPreference";
    else if (x instanceof ListPreference)
        return "ListPreference";
    else if (x instanceof MultiSelectListPreference)
        return "MultiSelectListPreference";
    else if (x instanceof RingtonePreference)
        return "RingtonePreference";
    else if (x instanceof SwitchPreference)
        return "SwitchPreference";
    else if (x instanceof TwoStatePreference)
        return "TwoStatePreference";
    else if (x instanceof DialogPreference) // Needs to be after ListPreference
        return "DialogPreference";
    else
        return "undefined";
}

Erstellen Sie eine 'setSummaryInit'-Methode.

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        Log.i(TAG, "+ onSharedPreferenceChanged(prefs:" + prefs + ", key:" + key + ")");
        if( key != null ) {
            updatePreference(prefs, key);
            setSummary(key);
        } else {
            Log.e(TAG, "Preference without key!");
        }
        Log.i(TAG, "- onSharedPreferenceChanged()");
    }

    protected boolean setSummary() {
        return _setSummary(null);
    }

    protected boolean setSummary(String sKey) {
        return _setSummary(sKey);
    }

    private boolean _setSummary(String sKey) {
        if (sKey == null) Log.i(TAG, "Initializing");
        else Log.i(TAG, sKey);

        // Get Preferences
        SharedPreferences sharedPrefs = PreferenceManager
                .getDefaultSharedPreferences(this);

        // Iterate through all Shared Preferences
        // http://stackoverflow.com/questions/9310479/how-to-iterate-through-all-keys-of-shared-preferences
        Map<String, ?> keys = sharedPrefs.getAll();
        for (Map.Entry<String, ?> entry : keys.entrySet()) {
            String key = entry.getKey();
            // Do work only if initializing (null) or updating specific preference key
            if ( (sKey == null) || (sKey.equals(key)) ) {
                String value = entry.getValue().toString();
                Preference pref = findPreference(key);
                String preference = getPreference(pref);
                Log.d("map values", key + " | " + value + " | " + preference);
                pref.setSummary(key + " | " + value + " | " + preference);
                if (sKey != null) return true;
            }
        }
        return false;
    }

    private void updatePreference(SharedPreferences prefs, String key) {
        Log.i(TAG, "+ updatePreference(prefs:" + prefs + ", key:" + key + ")");
        Preference pref = findPreference(key);
        String preferenceType = getPreference(pref);
        Log.i(TAG, "preferenceType = " + preferenceType);
        Log.i(TAG, "- updatePreference()");
    }

Initialisieren

Erstellen Sie eine öffentliche Klasse, die PreferenceActivity und OnSharedPreferenceChangeListener implementiert

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    PreferenceManager.setDefaultValues(this, R.xml.global_preferences,
    false);
    this.addPreferencesFromResource(R.xml.global_preferences);
    this.getPreferenceScreen().getSharedPreferences()
        .registerOnSharedPreferenceChangeListener(this);
}

protected void onResume() {
    super.onResume();
    setSummary();
}
3
Page2PagePro

Einfach:

listPreference.setSummary("%s");
3
Oded Breiner

Wenn Sie nur den Nur-Text-Wert jedes Felds als Zusammenfassung anzeigen möchten, sollte der folgende Code am einfachsten zu verwalten sein. Es sind nur zwei Änderungen erforderlich (Zeilen 13 und 21, die mit "change here" gekennzeichnet sind):

package com.my.package;

import Android.content.SharedPreferences;
import Android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import Android.os.Bundle;
import Android.preference.EditTextPreference;
import Android.preference.ListPreference;
import Android.preference.Preference;
import Android.preference.PreferenceActivity;

public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {

    private final String[] mAutoSummaryFields = { "pref_key1", "pref_key2", "pref_key3" }; // change here
    private final int mEntryCount = mAutoSummaryFields.length;
    private Preference[] mPreferenceEntries;

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences_file); // change here
        mPreferenceEntries = new Preference[mEntryCount];
        for (int i = 0; i < mEntryCount; i++) {
            mPreferenceEntries[i] = getPreferenceScreen().findPreference(mAutoSummaryFields[i]);
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onResume() {
        super.onResume();
        for (int i = 0; i < mEntryCount; i++) {
            updateSummary(mAutoSummaryFields[i]); // initialization
        }
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); // register change listener
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); // unregister change listener
    }

    private void updateSummary(String key) {
        for (int i = 0; i < mEntryCount; i++) {
            if (key.equals(mAutoSummaryFields[i])) {
                if (mPreferenceEntries[i] instanceof EditTextPreference) {
                    final EditTextPreference currentPreference = (EditTextPreference) mPreferenceEntries[i];
                    mPreferenceEntries[i].setSummary(currentPreference.getText());
                }
                else if (mPreferenceEntries[i] instanceof ListPreference) {
                    final ListPreference currentPreference = (ListPreference) mPreferenceEntries[i];
                    mPreferenceEntries[i].setSummary(currentPreference.getEntry());
                }
                break;
            }
        }
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        updateSummary(key);
    }

}
3
caw

Zu Ihrer Information:

findPreference(CharSequence key)
This method was deprecated in API level 11. This function is not relevant
for a modern fragment-based PreferenceActivity.

Umso mehr sollte man sich die sehr glatte Answer von @ASD ( source hier ) anschauen, die besagt, dass %s in Android:summary für jedes Feld in preferences.xml verwendet werden soll. (Der aktuelle Präferenzwert wird durch %s ersetzt.)

 enter image description here

<ListPreference
 ...        
 Android:summary="Length of longest Word to return as match is %s"
 ...
 />
3
DSlomer64

Für EditTextPreference :

Ich bin natürlich zu dieser Lösung gekommen, nur wenn Sie bestimmte Voreinstellungen benötigen, aber Sie könnten dies mit jeder Präferenz tun:

............

private static final String KEY_EDIT_TEXT_PREFERENCE2 = "on_a1";
public static  String value = "";

............

private void updatePreference(Preference preference, String key) {

            if (key.equals(KEY_EDIT_TEXT_PREFERENCE2)) {
                preference = findPreference(key);
                if (preference instanceof EditTextPreference) {
                    editTextPreference = (EditTextPreference) preference;
                    editTextPreference.setSummary(editTextPreference.getText());
                    value = editTextPreference.getText().toString();
                    return;
                }
                SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
                preference.setSummary(sharedPrefs.getString(KEY_EDIT_TEXT_PREFERENCE2, ""));

            }
}

Dann in onResume ();

@Override
        public void onResume() {
            super.onResume();

            SharedPreferences etext = getPreferenceManager().getSharedPreferences();
            String str = etext.getString("value", "");
            editTextPreference = (EditTextPreference) findPreference(KEY_EDIT_TEXT_PREFERENCE2);
            editTextPreference.setText(str);
            editTextPreference.setSummary(editTextPreference.getText());

            getPreferenceScreen().getSharedPreferences()
                    .registerOnSharedPreferenceChangeListener(this);
        }

Im:

@Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            updatePreference(findPreference(key), key);
}
2
Stanojkovic

Hier werden alle diese Elemente aus dem Eclipse-Beispiel SettingsActivity..__ herausgeschnitten. Ich muss all diese zu vielen Codes kopieren, um zu zeigen, wie sich diese Android-Entwickler perfekt für einen allgemeineren und stabileren Codierstil entscheiden.

Ich habe die Codes für die Anpassung der PreferenceActivity an das Tablet und die größere API gelassen.

public class SettingsActivity extends PreferenceActivity {

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);

    setupSummaryUpdatablePreferencesScreen();
}

private void setupSummaryUpdatablePreferencesScreen() {

    // In the simplified UI, fragments are not used at all and we instead
    // use the older PreferenceActivity APIs.

    // Add 'general' preferences.
    addPreferencesFromResource(R.xml.pref_general);

    // Bind the summaries of EditText/List/Dialog preferences to
    // their values. When their values change, their summaries are updated
    // to reflect the new value, per the Android Design guidelines.
    bindPreferenceSummaryToValue(findPreference("example_text"));
    bindPreferenceSummaryToValue(findPreference("example_list"));
}

/**
 * A preference value change listener that updates the preference's summary
 * to reflect its new value.
 */
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {

    private String TAG = SettingsActivity.class.getSimpleName();

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

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list.
            ListPreference listPreference = (ListPreference) preference;
            int index = listPreference.findIndexOfValue(stringValue);

            // Set the summary to reflect the new value.
            preference.setSummary(
                index >= 0
                ? listPreference.getEntries()[index]
                : null);
        } else {
            // For all other preferences, set the summary to the value's
            // simple string representation.
            preference.setSummary(stringValue);
        }
        Log.i(TAG, "pref changed : " + preference.getKey() + " " + value);
        return true;
    }
};

/**
 * Binds a preference's summary to its value. More specifically, when the
 * preference's value is changed, its summary (line of text below the
 * preference title) is updated to reflect the value. The summary is also
 * immediately updated upon calling this method. The exact display format is
 * dependent on the type of preference.
 *
 * @see #sBindPreferenceSummaryToValueListener
 */

private static void bindPreferenceSummaryToValue(Preference preference) {
    // Set the listener to watch for value changes.
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

    // Trigger the listener immediately with the preference's
    // current value.
    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                                                             PreferenceManager
                                                             .getDefaultSharedPreferences(preference.getContext())
                                                             .getString(preference.getKey(), ""));
}

}

xml/pref_general.xml

<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android" >

<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<EditTextPreference
Android:capitalize="words"
Android:defaultValue="@string/pref_default_display_name"
Android:inputType="textCapWords"
Android:key="example_text"
Android:maxLines="1"
Android:selectAllOnFocus="true"
Android:singleLine="true"
Android:title="@string/pref_title_display_name" />

<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog todismiss it.-->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
<ListPreference
Android:defaultValue="-1"
Android:entries="@array/pref_example_list_titles"
Android:entryValues="@array/pref_example_list_values"
Android:key="example_list"
Android:negativeButtonText="@null"
Android:positiveButtonText="@null"
Android:title="@string/pref_title_add_friends_to_messages" />

</PreferenceScreen>

values/strings_activity_settings.xml

<resources>
<!-- Strings related to Settings -->

<!-- Example General settings -->

<string name="pref_title_display_name">Display name</string>
<string name="pref_default_display_name">John Smith</string>

<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
</resources>

HINWEIS: Eigentlich möchte ich nur kommentieren wie "Googles Beispiel für PreferenceActivity ist auch interessant". Aber ich habe nicht genug Reputationspunkte. Also beschuldige mich nicht.

(Entschuldige mein schlechtes Englisch)

2
johnkarka

Sie müssen die Funktion bindPreferenceSummaryToValue für die onCreate-Methode verwenden.

Beispiel:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Add 'general' preferences, defined in the XML file
        addPreferencesFromResource(R.xml.pref_general);

        // For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
        // updated when the preference changes.
        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key)));
    }

Siehe Lektion 3 zu Udacity Android Course: https://www.udacity.com/course/viewer#!/c-ud853/l-1474559101/e-1643578599/m-1643578601

2
Pablo

Meine Lösung ist das Erstellen einer benutzerdefinierten EditTextPreference, die in XML wie folgt verwendet wird: <com.example.EditTextPreference Android:title="Example Title" />

EditTextPreference.Java : -

package com.example;

import Android.content.Context;
import Android.util.AttributeSet;

public class EditTextPreference extends Android.preference.EditTextPreference
{
    public EditTextPreference(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public EditTextPreference(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public EditTextPreference(Context context)
    {
        super(context, null);
    }

    @Override
    protected void onDialogClosed(boolean positiveResult)
    {
        super.onDialogClosed(positiveResult);

        setSummary(getSummary());
    }

    @Override
    public CharSequence getSummary()
    {
        return getText();
    }
}
2
Salman Abbas

Da die Preference-Klasse in androidx die Schnittstelle SummaryProvider hat, kann auf OnSharedPreferenceChangeListener verzichtet werden. Einfache Implementierungen werden für EditTextPreference und ListPreference bereitgestellt. Aufbauend auf der Antwort von EddieB kann so aussehen. Getestet auf androidx.preference: Präferenz: 1.1.0-alpha03.

package com.example.util.timereminder.ui.prefs;

import Android.os.Bundle;

import com.example.util.timereminder.R;

import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;

/**
 * Displays different preferences.
 */
public class PrefsFragmentExample extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);

        initSummary(getPreferenceScreen());
    }

    /**
     * Walks through all preferences.
     *
     * @param p The starting preference to search from.
     */
    private void initSummary(Preference p) {
        if (p instanceof PreferenceGroup) {
            PreferenceGroup pGrp = (PreferenceGroup) p;
            for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
                initSummary(pGrp.getPreference(i));
            }
        } else {
            setPreferenceSummary(p);
        }
    }

    /**
     * Sets up summary providers for the preferences.
     *
     * @param p The preference to set up summary provider.
     */
    private void setPreferenceSummary(Preference p) {
        // No need to set up preference summaries for checkbox preferences because
        // they can be set up in xml using summaryOff and summary On
        if (p instanceof ListPreference) {
            p.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
        } else if (p instanceof EditTextPreference) {
            p.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());
        }
    }
}
1
Razeeman

Da ich eine benutzerdefinierte PreferenceDataStore verwende, kann ich keiner SharedPreference einen Listener hinzufügen. Daher musste ich eine etwas hackige Lösung schreiben, die auf jede Präferenz hört:

class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
    private val handler: Handler by lazy { Handler(Looper.getMainLooper()) }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        preferenceManager.preferenceDataStore = prefs
        addPreferencesFromResource(R.xml.app_preferences)
        onPreferenceChange(preferenceScreen, null)
    }

    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
        preference.onPreferenceChangeListener = this

        when (preference) {
            is PreferenceGroup -> for (i in 0 until preference.preferenceCount) {
                onPreferenceChange(preference.getPreference(i), null)
            }
            is ListPreference -> {
                if (preference.value == null) {
                    preference.isPersistent = false
                    preference.value = Preference::class.Java.getDeclaredField("mDefaultValue")
                            .apply { isAccessible = true }
                            .get(preference).toString()
                    preference.isPersistent = true
                }

                postPreferenceUpdate(Runnable { preference.summary = preference.entry })
            }
        }
        return true
    }

    /**
     * We can't directly update the preference summary update because [onPreferenceChange]'s result
     * is used to decide whether or not to update the pref value.
     */
    private fun postPreferenceUpdate(r: Runnable) = handler.post(r)
}
1
SUPERCILEX

Um die Zusammenfassung einer ListPreference auf den in einem Dialog ausgewählten Wert festzulegen, können Sie diesen Code verwenden:

package yourpackage;

import Android.content.Context;
import Android.util.AttributeSet;

public class ListPreference extends Android.preference.ListPreference {

    public ListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);
        if (positiveResult) setSummary(getEntry());
    }

    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        super.onSetInitialValue(restoreValue, defaultValue);
        setSummary(getEntry());
    }
}

und verweisen Sie auf das yourpackage.ListPreference-Objekt in Ihrem preferences.xml. Denken Sie daran, dort Ihren Android:defaultValue anzugeben, da dies den Aufruf von onSetInitialValue() auslöst.

Wenn Sie möchten, können Sie den Text vor dem Aufruf von setSummary() entsprechend Ihren Anforderungen ändern.

1
gicci

Entsprechend Android docs können Sie app:useSimpleSummaryProvider="true" in ListPreference- und EditTextPreference-Komponenten verwenden.

0
alishir

Wenn Sie AndroidX verwenden, können Sie eine benutzerdefinierte SummaryProvider verwenden . Dieser Ansatz kann für jede Preference verwendet werden.

Beispiel aus der Dokumentation (Java):

EditTextPreference countingPreference = (EditTextPreference) findPreference("counting");

countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
    @Override
    public CharSequence provideSummary(EditTextPreference preference) {
        String text = preference.getText();
        if (TextUtils.isEmpty(text)){
            return "Not set";
        }
        return "Length of saved value: " + text.length();
    }
});

Beispiel aus der Dokumentation (Kotlin):

val countingPreference = findPreference("counting") as EditTextPreference

countingPreference.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (TextUtils.isEmpty(text)) {
        "Not set"
    } else {
        "Length of saved value: " + text.length
    }
}
0
Andrew Churilo

Ich habe diesen Weg gefunden, um EditTextPreference aus der Unterstützungsbibliothek in der Zusammenfassung "%s" zusammenzufassen (da ListPreference bereits behandelt):

public class EditTextPreference extends Android.support.v7.preference.EditTextPreference {
    public EditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setText(String text) {
        super.setText(text);
        notifyChanged();
    }

    @Override
    public CharSequence getSummary() {
        String text = super.getText();
        String summary = super.getSummary().toString();
        return String.format(summary, text == null ? "" : text);
    }
}

In XML sieht es so aus:

<com.example.yourapp.EditTextPreference
    Android:defaultValue="1"
    Android:key="cleanup_period"
    Android:summary="Clean up messages after %s days"
    Android:title="Clean up period" />
0

Hier ist eine funktionierende Lösung für alle EditTextPreferences innerhalb einer PreferenceFragment basierend auf @tdeveaux Antwort

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    private static final String TAG = "SettingsFragment";

    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onResume () {
        super.onResume();

        for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) {
            Preference preference = getPreferenceScreen().getPreference(i);
            updatePreference(preference);
        }
    }

    @Override
    public void onSharedPreferenceChanged (SharedPreferences sharedPreferences, String key) {
        updatePreference(findPreference(key));
    }

    private void updatePreference (Preference preference) {
        if (preference instanceof EditTextPreference) {
            EditTextPreference editTextPreference = (EditTextPreference)preference;
            editTextPreference.setSummary(editTextPreference.getText());
        }
    }
}
0
kjdion84