Отображение значения EditTextPreference в сводке
Я изучаю, как развиваться в Android и хочу сделать настройку,
Моя активность настройки
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();
}
}
и мой res/preferences.xml
файл
<?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>
Итак, теперь у меня есть активность для активности настройки. Но я хочу показать значение EditTextPref в android:summary
.
Я нашел много тем, но все функции были устаревшими.
EDIT: благодаря @Ace_McIntosh, я редактировал свой код для людей, которые этого хотят, теперь он работает.
Ответы
Ответ 1
Просто используйте setSummary method на желаемом объекте Preference. Назовите его, возобновив фрагмент настроек для каждой записи, которую вы хотите обновить (т.е. Все записи EditTextPreference
в вашем случае) и зарегистрируйте OnSharedPreferenceChangeListener
на конкретном объекте SharedPreferences
(чтобы вы могли обновить сводку в если он изменен) - и передайте ему желаемое значение EditTextPreference (которое вы можете получить с помощью метода getText()
).
Реализуйте его в своем MyPreferenceFragment
, как это (я не гарантирую, что он будет работать с самого начала, он служит цели, чтобы просто дать вам идею):
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 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 summary value to its current text
preference.setSummary(preference.getText());
}
}
Ответ 2
Просто переопределите getSummary
для EditTextPreference
, и вы получите EditTextPreference, значение которого отображается в виде сводки.
public class EditSummaryPreference extends EditTextPreference {
...// omit constructor
@Override
public CharSequence getSummary() {
return getText();
}
}
Ответ 3
Самый простой способ - создать собственный класс EditTextPreference (изменен для компиляции):
package your.package;
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());
}
}
И используйте это в своем xml:
<your.package.EditTextPreference
android:key="pref_alpha"
android:summary="Actual value: %s"
android:title="Title"
android:defaultValue="default"
/>
Ответ 4
(В Kotlin) Я бы предпочел сделать что-то более простое и просто создать класс, который расширяет 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
}
}
Затем вы можете использовать это так:
<
<Имя пакета> .SummarisedEditTextPreference/>
Ответ 5
Там некоторые ошибки в примере выше, поэтому я решил опубликовать рабочее решение (также поддерживает ListPreference и MultiSelectListPreference)
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());
}
}
Ответ 6
Ответ @serv-inc работал у меня. Как-то другие ответы работали только при изменении значения.
Но прежде чем это сработало, мне пришлось внести изменения, как показано ниже:
@Override
public CharSequence getSummary() {
return getText();
}
Показывает значение, когда оно отображается, когда изменяется значение, а также после возобновления.
Ответ 7
Построение Uppon Ответ Бретта Черрингтона, реализация в Котлине. Была ошибка, а именно то, что PreferenceCategories не поддерживались, что исправлено с помощью дополнительного рекурсивного цикла в 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
}
}
Ответ 8
В библиотеке androidx EditTextPreference имеет атрибут app: useSimpleSummaryProvider. Используя атрибут, вам не нужно расширять какой-либо класс или прослушивать какие-либо изменения в SharedPreferences. Вы можете проверить пример кода по адресу https://github.com/googlesamples/android-preferences/blob/master/app/src/main/res/xml/dialogs.xml.
Ответ 9
В дополнение к @Eke Koseoglu ответ.
Если вы используете библиотеку настроек AndroidX, вы можете установить summaryProvider из кода Kotlin ниже.
val editTextPreference = EditTextPreference(context)
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
Согласно документации EditTextPreference.SimpleSummaryProvider;
Если значение не было установлено, отображаемая сводка будет "Не установлена", в противном случае отображаемая сводка будет значением, установленным для этого предпочтения.