Display the value of the EditTextPreference in summary [duplicate] - android
This question already has answers here:
How do I display the current value of an Android Preference in the Preference summary?
(35 answers)
Closed 2 years ago.
I'm a learning how to develop in Android and want to make a setting activity,
My setting activity
public class Main extends Activity {
protected SettingsFragment settingsFragment;
#SuppressLint("NewApi")
#TargetApi(11)
public class SettingsFragment extends PreferenceFragment implements
SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
setSummaries();
}
#Override
public void onResume() {
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
super.onResume();
sh.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
super.onPause();
sh.unregisterOnSharedPreferenceChangeListener(this);
}
#SuppressLint("NewApi")
public void setSummaries(){
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
//Pref1
Preference stylePref = findPreference("editTextPref");
stylePref.setSummary(sh.getString("editTextPref", ""));
//here the other preferences..
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("editTextPref")) {
Preference pref = settingsFragment.findPreference(key);
// Set summary to be the user-description for the selected value
pref.setSummary(sharedPreferences.getString(key, ""));
}
//here the others preferences
}
}//End fragment
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
}
and my res/preferences.xml file
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="BTA"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:key="editTextPref"
android:title="Numero de telephone"
android:summary="This allows you to enter a string"
android:defaultValue="*"/>
</PreferenceCategory>
</PreferenceScreen>
So now i have the activity for the setting activity. But i want to display the value of the EditTextPref in android:summary.
I have found many topics but all the functions was deprecated.
EDIT : thanks to #Ace_McIntosh , I edited my code for people who want it, it's working now.
If you are using AndroidX Preference library you can use the property app:useSimpleSummaryProvider. For example:
<EditTextPreference
app:key="edittext"
app:title="#string/title_edittext_preference"
app:useSimpleSummaryProvider="true"
app:dialogTitle="#string/dialog_title_edittext_preference"/>
You can read a fully working example here.
Just override getSummary of EditTextPreference, then you will get a EditTextPreference with its value displayed as summary.
public class EditSummaryPreference extends EditTextPreference {
...// omit constructor
#Override
public CharSequence getSummary() {
return getText();
}
}
Just use the setSummary method on the desired Preference object. Call it upon resuming your settings fragment for each entry that you wish to update (i.e., all the EditTextPreference entries in your case) and register an OnSharedPreferenceChangeListener on the concrete SharedPreferences object (so that you can update the summary in case it is changed) – and pass it the desired EditTextPreference's value (which you can obtain via its getText() method).
Implement it in your MyPreferenceFragment like this (I don't guarantee that it will work right of the bat, it serves the purpose to just give you an idea):
public class MyPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// load the preferences from your XML resource (which I assume you already do anyway)
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onResume() {
super.onResume();
sharedPreferences = getPreferenceManager().getSharedPreferences();
// we want to watch the preference values' changes
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
Map<String, ?> preferencesMap = sharedPreferences.getAll();
// iterate through the preference entries and update their summary if they are an instance of EditTextPreference
for (Map.Entry<String, ?> preferenceEntry : preferencesMap.entrySet()) {
if (preferenceEntry instanceof EditTextPreference) {
updateSummary((EditTextPreference) preferenceEntry);
}
}
}
#Override
public void onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
Map<String, ?> preferencesMap = sharedPreferences.getAll();
// get the preference that has been changed
Object changedPreference = preferencesMap.get(key);
// and if it's an instance of EditTextPreference class, update its summary
if (preferencesMap.get(key) instanceof EditTextPreference) {
updateSummary((EditTextPreference) changedPreference);
}
}
private void updateSummary(EditTextPreference preference) {
// set the EditTextPreference's summary value to its current text
preference.setSummary(preference.getText());
}
}
(In Kotlin) I would prefer to do something a bit more simple and just create a class which extends the EditTextPreference:
import android.content.Context
import android.support.v7.preference.EditTextPreference
import android.util.AttributeSet
/**
* This class was created by Anthony M Cannon on 17/04/2018.
*/
class SummarisedEditTextPreference #JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null) : EditTextPreference(context, attrs) {
private var mOnChangeListener: OnPreferenceChangeListener? = null
init {
super.setOnPreferenceChangeListener { preference, newValue ->
summary = newValue as String
mOnChangeListener?.onPreferenceChange(preference, newValue) ?: true
}
}
/**
* Called when this Preference has been attached to a Preference hierarchy.
* Make sure to call the super implementation.
*
* #param preferenceManager The PreferenceManager of the hierarchy.
*/
override fun onAttachedToHierarchy(preferenceManager: PreferenceManager) {
super.onAttachedToHierarchy(preferenceManager)
summary = sharedPreferences.getString(key, null)
}
/**
* Sets the callback to be invoked when this Preference is changed by the
* user (but before the internal state has been updated).
*
* #param onPreferenceChangeListener The callback to be invoked.
*/
override fun setOnPreferenceChangeListener(
onPreferenceChangeListener: OnPreferenceChangeListener) {
mOnChangeListener = onPreferenceChangeListener
}
}
You can then use this like so:
<<your package name>.SummarisedEditTextPreference/>
In androidx library, EditTextPreference has app:useSimpleSummaryProvider attribute. Using the attribute you won't need to extend any class or listen any changes on SharedPreferences. You can check the sample code at https://github.com/googlesamples/android-preferences/blob/master/app/src/main/res/xml/dialogs.xml
There's some bugs in the example posted above so I thought I post a working solution (supports ListPreference and MultiSelectListPreference as well)
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
#Override
public void onResume() {
super.onResume();
sharedPreferences = getPreferenceManager().getSharedPreferences();
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
PreferenceScreen preferenceScreen = getPreferenceScreen();
for(int i = 0; i < preferenceScreen.getPreferenceCount(); i++) {
setSummary(getPreferenceScreen().getPreference(i));
}
}
#Override
public void onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = getPreferenceScreen().findPreference(key);
setSummary(pref);
}
private void setSummary(Preference pref) {
if (pref instanceof EditTextPreference) {
updateSummary((EditTextPreference) pref);
} else if (pref instanceof ListPreference) {
updateSummary((ListPreference) pref);
} else if (pref instanceof MultiSelectListPreference) {
updateSummary((MultiSelectListPreference) pref);
}
}
private void updateSummary(MultiSelectListPreference pref) {
pref.setSummary(Arrays.toString(pref.getValues().toArray()));
}
private void updateSummary(ListPreference pref) {
pref.setSummary(pref.getValue());
}
private void updateSummary(EditTextPreference preference) {
preference.setSummary(preference.getText());
}
}
Answer of #serv-inc worked for me. Somehow other answers worked only when the value changes.
But before it worked, I had to make a change as below:
#Override
public CharSequence getSummary() {
return getText();
}
It shows the value when it is initially displayed, when value changes, as well as after resume.
Building uppon Brett Cherringtons answer, the implementation in Kotlin. There was a bug, namely that PreferenceCategories were not supported, which is fixed with an additional recursive loop in setSummary
class SettingsFragment : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
private lateinit var sharedPreferences: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.preferences)
}
override fun onResume() {
super.onResume()
sharedPreferences = preferenceManager.sharedPreferences
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
val preferenceScreen = preferenceScreen
for (i in 0 until preferenceScreen.preferenceCount) {
setSummary(getPreferenceScreen().getPreference(i))
}
}
override fun onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
super.onPause()
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
val pref = preferenceScreen.findPreference(key)
pref?.let { setSummary(it) }
}
private fun setSummary(pref: Preference) {
if (pref is EditTextPreference) {
updateSummary(pref)
} else if (pref is ListPreference) {
updateSummary(pref)
} else if (pref is MultiSelectListPreference) {
updateSummary(pref)
} else if (pref is PreferenceCategory){
// needs to loop through child preferences
for (i in 0 until pref.preferenceCount) {
setSummary(pref.getPreference(i))
}
}
}
private fun updateSummary(pref: MultiSelectListPreference) {
pref.setSummary(Arrays.toString(pref.values.toTypedArray()))
}
private fun updateSummary(pref: ListPreference) {
pref.summary = pref.value
}
private fun updateSummary(preference: EditTextPreference) {
preference.summary = preference.text
}
}
In addition to #Eke Koseoglu's answer.
If you use AndroidX preference library, you can set summaryProvider from Kotlin code below.
val editTextPreference = EditTextPreference(context)
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
According to documentation of EditTextPreference.SimpleSummaryProvider;
If no value has been set, the summary displayed will be 'Not set',
otherwise the summary displayed will be the value set for this
preference.
Related
Avoid code duplication in OnSharedPreferenceChangeListener
I currently have a service that loads preferences upon startup, stores them as fields, then registers an OnSharedPreferenceChangeListener to update the fields when a preference is modified. Currently, my code looks like this: public class MyService extends Service { private int _prefA; private boolean _prefB; private String _prefC; private boolean _prefD; private SharedPreferences _preferences; private SharedPreferences.OnSharedPreferenceChangeListener _prefChangeListener; #Override public void onCreate() { super.onCreate(); _preferences = PreferenceManager.getDefaultSharedPreferences(this); _prefA = Integer.parseInt(_preferences.getString(PREF_A_KEY, "0")); _prefB = _preferences.getBoolean(PREF_B_KEY, false); _prefC = _preferences.getString(PREF_C_KEY, null); _prefD = _preferences.getBoolean(PREF_D_KEY, false); _prefChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { #Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(PREF_A_KEY)) { _prefA = Integer.parseInt(sharedPreferences.getString(key, "0")); } else if (key.equals(PREF_B_KEY)) { _prefB = sharedPreferences.getBoolean(key, false); } else if (key.equals(PREF_C_KEY)) { _prefC = sharedPreferences.getString(key, null); } else if (key.equals(PREF_D_KEY)) { _prefD = sharedPreferences.getBoolean(key, false); } } }; _preferences.registerOnSharedPreferenceChangeListener(_prefChangeListener); } } It works as expected, but adding more preferences is becoming tedious, since I have to update the code in both onCreate() and OnSharedPreferenceChangeListener. Is there any way to change this so that the code to load the preferences only needs to be written once?
This is rather ideal. However, it reduced the overhead a little: Create initializer functions: private void initializeAccounts() { ... Resources res = getResources(); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); String User = preferences.getString(res.getString(R.string.username), null); String Pass = preferences.getString(res.getString(R.string.password), null); ... } And then group the preferences : #Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (getString(R.string.prefkey_password).equals(key) || getString(R.string.prefkey_username).equals(key)) { initializeAccounts(); } } In the onCreate: #Override public void onCreate(Bundle bundle) { super.onCreate(bundle); PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); initializeAccounts(); } The reason why I group the preferences together is that the other preferences don't change when I edit one of them. However, when I for instance want to change the password of my account, I also require the other preferences like username or the server URI to reconnect to the server. So, it more or less doesn't matter if I reset them. Hope this helps.
OnSharedPreferenceChangeListener not working in another thread task
When using a thread/task within an android service that implements the OnSharedPreferenceChangeListener interface, the changes made in the preference screen aren't reflected back to the thread/task object within the android service. I want to accomplish two things: SharedPreference data should be loaded when MyTask is constructed and initialized. When preference change occurs, MyTask object must be updated with the new preference values set in the preference screen. The problem is: preference initialization and preference changes are not reflected to the MyTask object. This is my setup (only essential parts are mentioned): MyService.class: public class MyService extends Sevice { private MyTask myTask; #Override public int onStartCommand(Intent intent, int flags, int startId) { if (!serviceStarted) { serviceStarted = true; myTask = new MyTask(this); Thread t = new Thread(myTask); t.start(); } return Service.START_STICKY; } #Override public void onDestroy() { myTask.cancel(); super.onDestroy(); } } MyTask.class: public MyTask implements Runnable, OnSharedPreferenceChangeListener { private Context mContext; private boolean mCancelled; public MyTask(Context context) { mContext = context; } #Override public void run() { while(!mCancelled) { // do something } } #Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // FIXME: DOESN'T GET CALLED after change in preference!!!! Log.d(TAG, "Key= " + key); } public void cancel() { mCancelled = true; } } preference_devices.xml: <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory android:key="pref_category_devices" android:title="#string/pref_category_devices_title" > <CheckBoxPreference android:defaultValue="true" android:key="pref_devices_server" android:title="#string/pref_devices_server_title" /> </PreferenceCategory> </PreferenceScreen> I have tried coding a SharedPreferences listener object as a member field of the MyTask class and register/unregister the listener from the provided context, but that didn't work either. These changes also didn't work: MyTask.class (using SharedPreference listener as field member of class): public MyTask implements Runnable { private Context mContext; private boolean mCancelled; private boolean mServerEnabled; private SharedPreferences mPrefs; private SharedPreferences.OnSharedPreferenceChangeListener mPreferenceListener; public MyTask(Context context) { mContext = context; mPrefs = mContext.getSharedPreferences("pref_category_devices", Context.MODE_PRIVATE); mPreferenceListener = new OnSharedPreferenceChangeListener() { #Override public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { // FIXME: DOESN'T GET CALLED after change in preference!!!! Log.d(TAG, "Key= " + key); } }; mPrefs.registerOnSharedPreferenceChangeListener(mPreferenceListener); // set the initial value of the preference setting mServerEnabled = mPrefs.getBoolean("pref_devices_server", false); } #Override public void run() { while(!mCancelled) { // do something } } public void cancel() { mCancelled = true; } } I have now reached the point of throwing my computer out of the window :( Any help in the right direction is highly appreciated :) EDIT: In the code mPrefs = mContext.getSharedPreferences("pref_category_devices", Context.MODE_PRIVATE); I assumed that the first argument should be the preference category name of the preference file, like: "pref_category_devices". THIS IS INCORRECT! The first argument must be a shared preference file name. That didn't solve the problem, but at least now you know to not fall for this pitfall. === SOLUTION: === See answer of Mr_and_Mrs_D + code below this line: Change in MyTask: mPrefs = mContext.getSharedPreferences("pref_category_devices", Context.MODE_PRIVATE); into: mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); mPreferenceListener = new OnSharedPreferenceChangeListener() { #Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals("preference_name_here")) { mPrefValue = sharedPreferences.getBoolean(key, false); // do something with boolean pref value } } }; mPrefs.registerOnSharedPreferenceChangeListener(myPreferenceListener); Where mPrefValue is a field member of type boolean in MyTask that needs to be set when the "preference_name_here" preference changes.
Change : private volatile boolean mCancelled; //otherwise the myTask thread may never stop For your problem : if (!serviceStarted) { serviceStarted = true; myTask = new MyTask(this); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); sp.registerOnSharedPreferenceChangeListener(myTask); //err, you must register Thread t = new Thread(myTask); t.start(); } Docs : These preferences will automatically save to SharedPreferences as the user interacts with them. To retrieve an instance of SharedPreferences that the preference hierarchy in this activity will use, call getDefaultSharedPreferences(android.content.Context) with a context in the same package as this activity. [emphasis mine] Edit : your second snippet probably fails cause you get the wrong shared prefs - you must get the default ones - I thought it was failing because of : SharedPreferences.onSharedPreferenceChangeListener not being called consistently
OnSharedPreferenceChangeListener not called #2
Okay I started to implement this horrible code from Google's android. The OnSharedPreferenceChangeListener is not being called. This is my code, can you please advice? Class definition: private SharedPreferences sPrefs; private PreferenceChangedListener prefsChangedListener; I have a private inner class: private class PreferenceChangedListener implements OnSharedPreferenceChangeListener { public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { if (key == "highThreshold") { try { highThreshold = Float.parseFloat(sharedPreferences .getString(key, "0")); } catch (Exception e) { } } } } Tried te following code in OnResume and to register the listener after the 'Voorkeuren' preferenceactivity is started. Both fail. sPrefs = getPreferences(MODE_PRIVATE); prefsChangedListener = new PreferenceChangedListener(); sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener ); I defined a class Voorkeuren which extends PreferenceActivity public class Voorkeuren extends PreferenceActivity { #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } #Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_voorkeuren, menu); return true; } } Which I open as following: Intent intent = new Intent(getBaseContext(),Voorkeuren.class); startActivity(intent); The class shows up fine, and stores the values between sessions. But my application should not be polling if settings chagned. Any ideas? I have red something about an SharedPreferences.Editor but I am not sure how it is related.
Not sure what your question is and what is desired. But there is one change that you need to do. Replace this in onResume sPrefs = getPreferences(MODE_PRIVATE); prefsChangedListener = new PreferenceChangedListener(); sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener ); to sPrefs = PreferenceManager.getDefaultSharedPreferences(this);; prefsChangedListener = new PreferenceChangedListener(); sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener); in onCreate()
Android PreferenceScreen onChangeListener not invoked
i wrote a simple PreferenceScreen, looks as follows: public class SettingsActivity extends PreferenceActivity implements OnPreferenceChangeListener { #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); PreferenceScreen prefScreen = getPreferenceScreen(); prefScreen.setOnPreferenceChangeListener(this); } #Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { if (preference.getTitle().equals(getString(R.string.settings_diverse_about))) { // TODO open about dialog } return super.onPreferenceTreeClick(preferenceScreen, preference); } private static String PATTERN_EMAIL = "[A-Z0-9._%-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}"; private static String PATTERN_TWITTER = "[a-zA-Z0-9_-]+"; #Override public boolean onPreferenceChange(Preference preference, Object newValue) { String prefTitle = preference.getTitle().toString(); // phone will be fully handled by inputType String newStr = newValue.toString(); if (prefTitle.equals(getString(R.string.settings_contact_email))) { return newStr.trim().matches(PATTERN_EMAIL); } else if (prefTitle.equals(getString(R.string.settings_contact_twitter))) { return newStr.trim().matches(PATTERN_TWITTER); } return true; } The problem is, the onPreferenceChange method gets never invoked. Furthermore, what do you think about the way of validating the attributes? I think it's not really optimal. preference.getTitle().equals(getString(R.string.settings_diverse_about))
I had the same problem. I tried to set up a onPreferenceChangeListener but that was wrong. What I really needed was an onSharedPreferenceListener. OnSharedPreferenceChangeListener listener; Write this in the onCreate() of your Preference activity: listener = new SharedPreferences.OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { // Here you can work. // IMPORTANT: Beware that at this point the preference has already been changed! } }; SharedPreferences prefs = getSharedPreferences(getPackageName() + "_preferences", MODE_PRIVATE); prefs.registerOnSharedPreferenceChangeListener(listener);
How do I display the current value of an Android Preference in the Preference summary?
This must come up very often. When the user is editing preferences in an Android app, I'd like them to be able to see the currently set value of the preference in the Preference summary. Example: if I have a Preference setting for "Discard old messages" that specifies the number of days after which messages need to be cleaned up. In the PreferenceActivity I'd like the user to see: "Discard old messages" <- title "Clean up messages after x days" <- summary where x is the current Preference value Extra credit: make this reusable, so I can easily apply it to all my preferences regardless of their type (so that it work with EditTextPreference, ListPreference etc. with minimal amount of coding).
There are ways to make this a more generic solution, if that suits your needs. For example, if you want to generically have all list preferences show their choice as summary, you could have this for your onSharedPreferenceChanged implementation: public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Preference pref = findPreference(key); if (pref instanceof ListPreference) { ListPreference listPref = (ListPreference) pref; pref.setSummary(listPref.getEntry()); } } This is easily extensible to other preference classes. And by using the getPreferenceCount and getPreference functionality in PreferenceScreen and PreferenceCategory, you could easily write a generic function to walk the preference tree setting the summaries of all preferences of the types you desire to their toString representation
Here is my solution... 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()); } } }
Android documentation says one can use a String formatting marker in getSummary(): If the summary has a String formatting marker in it (i.e. "%s" or "%1$s"), then the current entry value will be substituted in its place. Simply specifying android:summary="Clean up messages after %s days" in ListPreference xml declaration worked for me. Note: This only works for ListPreference.
If you use PreferenceFragment, this is how I solved it. It's self explanatory. 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")); } }
My option is to extend ListPreference and it's clean: 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(); } } Then you add in your settings.xml: <yourpackage.ListPreferenceShowSummary android:key="key" android:title="title" android:entries="#array/entries" android:entryValues="#array/values" android:defaultValue="first value"/>
You can override default Preference classes and implement the feature. 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()); } } Later in you xml you can use custom preference like <your.package.name.MyListPreference android:key="noteInterval" android:defaultValue="60" android:title="Notification Interval" android:entries="#array/noteInterval" android:entryValues="#array/noteIntervalValues" />
After several hours I've been spent to solve such problem I've implemented this code: [UPDATE: the final version listing] 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); } } That was the only solution that worked for me fine. Before I've tried to subclass from ListPreferences and to implement android:summary="bla bla bla %s". Neither worked.
Maybe like ListPreference: Modify getSummary to get what you want: 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()); } } And use this in your xml: <your.package.EditTextPreference android:key="pref_alpha" android:summary="Actual value: %s" android:title="Title" android:defaultValue="default" /> So you are able to write a summary with %s instead of the actual value.
This is the code you need to set the summary to the chosen value. It also sets the values on startup and respects the default values, not only on change. Just change "R.layout.prefs" to your xml-file and extend the setSummary-method to your needs. It actually is only handling ListPreferences, but it is easy to customize to respect other Preferences. 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
For 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); } }
According to Android docs you can use app:useSimpleSummaryProvider="true" in ListPreference and EditTextPreference components.
Actually, CheckBoxPreference does have the ability to specify a different summary based on the checkbox value. See the android:summaryOff and android:summaryOn attributes (as well as the corresponding CheckBoxPreference methods).
If someone is still looking for answers to this, you should check out thirtythreefortys answer. <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 will replace %s with the current string value of the preference, as displayed by the ListPreference's picker.
Thanks for this tip! I have one preference screen and want to show the value for each list preference as the summary. This is my way now: 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()); } } This works for me, but I'm wondering what is the best solution (performance, stability, scalibility): the one Koem is showing or this one?
I've seen all voted answers show how to set the summary with the exact current value, but the OP wanted also something like: "Clean up messages after x days"* <- summary where x is the current Preference value Here is my answer for achieving that As per the documentation on ListPreference.getSummary(): Returns the summary of this ListPreference. If the summary has a String formatting marker in it (i.e. "%s" or "%1$s"), then the current entry value will be substituted in its place. However, I tried this on several devices and it doesn't seem to work. With some research, I found a good solution in this answer. It simply consists of extending every Preference you use and override getSummary() to work as specified by Android documentation.
Thanks, Reto, for the detailed explanation! In case this is of any help to anyone, I had to change the code proposed by Reto Meier to make it work with the SDK for Android 1.5 #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 ... } The same change applies for the callback function onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) Cheers, Chris
In Android Studio, open "root_preferences.xml", select Design mode. Select the desired EditTextPreference preference, and under "All attributes", look for the "useSimpleSummaryProvider" attribute and set it to true. It will then show the current value.
I solved the issue with the following descendant of ListPreference: 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; } } } Seems to work fine for me in 1.6 up through 4.0.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; } }
If you only want to display the plain text value of each field as its summary, the following code should be the easiest to maintain. It requires only two changes (lines 13 and 21, marked with "change here"): 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); } }
Here's my solution: Build a preference type 'getter' method. 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"; } Build a 'setSummaryInit' method. 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()"); } Initialize Create public class that PreferenceActivity and implements OnSharedPreferenceChangeListener 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(); }
Simply: listPreference.setSummary("%s");
FYI: findPreference(CharSequence key) This method was deprecated in API level 11. This function is not relevant for a modern fragment-based PreferenceActivity. All the more reason to look at the very slick Answer of #ASD above (source found here) saying to use %s in android:summary for each field in preferences.xml. (Current value of preference is substituted for %s.) <ListPreference ... android:summary="Length of longest word to return as match is %s" ... />
Since in androidx Preference class has the SummaryProvider interface, it can be done without OnSharedPreferenceChangeListener. Simple implementations are provided for EditTextPreference and ListPreference. Building on EddieB's answer it can look like this. Tested on androidx.preference:preference: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()); } } }
Here,all these are cut from Eclipse sample SettingsActivity. I have to copy all these too much codes to show how these android developers choose perfectly for more generalized and stable coding style. I left the codes for adapting the PreferenceActivity to tablet and greater API. 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> NOTE: Actually I just want to comment like "Google's sample for PreferenceActivity is also interesting". But I haven't enough reputation points.So please don't blame me. (Sorry for bad English)
You have to use bindPreferenceSummaryToValue function on the onCreate method. Example: #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))); } See lesson 3 on Udacity Android Course: https://www.udacity.com/course/viewer#!/c-ud853/l-1474559101/e-1643578599/m-1643578601
For EditTextPreference: I came to this solution, of course, just if you need particular edittextpreference but you could do this with every Preference: ............ 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, "")); } } Then 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); } In: #Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { updatePreference(findPreference(key), key); }
My solution is to create a custom EditTextPreference, used in XML like this: <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(); } }
If you are using AndroidX you can use a custom SummaryProvider. This approach can be used for any Preference. Example from documentation (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(); } }); Example from documentation (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 } }
To set the summary of a ListPreference to the value selected in a dialog you could use this code: 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()); } } and reference the yourpackage.ListPreference object in your preferences.xml remembering to specify there your android:defaultValue as this triggers the call to onSetInitialValue(). If you want you can then modify the text before calling setSummary() to whatever suits your application.