Reputation: 73
I've been struggling with this issue for a while now so I decided to ask here what I' m doing wrong.
First of all: - I have a PreferenceFragment with a ListPreference on top and an EditTextPreference below - The ListPreference is filled with Objects, the values are stored in a file and read from there (this works flawlessly) - The EditTextPreference should display the value of the in the ListPreference chosen object. And that's the problem: after choosing the value nothing changes so I have to click the ListPreference once more and the value is set correctly. Is this a problem with my Listener?
Here's the code:
public class SettingsTestFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private final String[] pref_key_array = {"pref_key_lp", "pref_key_et""}; // array that contains all the preference keys of changeable values
private final int numberOfEntries = pref_key_array.length;
private Preference[] pref_entries;
String[] entries = {"Value 1", "Value 2", "Value 3"};
String[] entryValues = {"0", "1", "2"};
private int position;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
final SharedPreferences myPreference = PreferenceManager.getDefaultSharedPreferences(getActivity());
final EditTextPreference et = (EditTextPreference) findPreference("pref_key_et");
final ListPreference lp = (ListPreference) findPreference("pref_key_lp");
prepareListPref(lp);
pref_entries = new Preference[numberOfEntries];
for(int i = 0; i < numberOfEntries; i++) {
pref_entries[i] = getPreferenceScreen().findPreference(pref_key_array[i]);
}
lp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
position = Integer.valueOf(myPreference.getString("pref_key_lp", "0"));
et.setText(entries[position]);
return true;
}
});
Preference.OnPreferenceChangeListener changeListener = new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
position = Integer.valueOf(myPreference.getString("pref_key_lp", "0"));
preference.setSummary(entries[position]);
return true;
}
};
lp.setOnPreferenceChangeListener(changeListener);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updateSummary(key, pref_key_array, numberOfEntries, pref_entries);
}
@Override
public void onResume() {
super.onResume();
// Set up listener when a key changes
for(int i = 0; i < numberOfEntries; i++) {
updateSummary(pref_key_array[i], pref_key_array, numberOfEntries, pref_entries);
}
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
// Unregister listener every time a key changes
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
public void prepareListPref(ListPreference lp) {
lp.setEntries(entries);
lp.setEntryValues(entryValues);
lp.setDefaultValue("0");
}
public void updateSummary(String key, String[] pref_key_array, int numberOfEntries, Preference[] pref_entries) {
for(int i = 0; i < numberOfEntries; i++) {
if(key.equals(pref_key_array[i])) {
if(pref_entries[i] instanceof EditTextPreference) {
final EditTextPreference currentPreference = (EditTextPreference) pref_entries[i];
pref_entries[i].setSummary(currentPreference.getText());
} else if(pref_entries[i] instanceof ListPreference) {
final ListPreference currentPreference = (ListPreference) pref_entries[i];
pref_entries[i].setSummary(currentPreference.getEntry());
}
break;
}
}
}
}
Summarizing the code for reading from the file and writing the value to the Settings works but only after clicking the ListPreference a second time. Do you have any ideas why?
Thanks
Upvotes: 2
Views: 663
Reputation: 115972
ok, I'm not sure what you are trying to do and what is the problem, so I've made a sample, showing the next thing:
I still think you should consider making a custom Preference class, as you wrote that you intend to use a lot of couples of ListPreference&EditTextPreference.
BTW, code is based on an app that I've made (link here). I've made it so that it will be easy to handle multiple listPreferences easier.
Here's the code:
res/values/strings_activity_settings.xml
<resources>
<string name="pref__custom_app_theme" translatable="false">pref__custom_app_theme</string>
<string name="pref__app_theme" translatable="false">pref__app_theme</string>
<string-array name="pref__app_theme_entries">
<item>@string/cards_light</item>
<item>@string/cards_dark</item>
</string-array>
<string name="pref__app_theme__cards_ui" translatable="false">CARDS_UI</string>
<string name="pref__app_theme__cards_ui_dark" translatable="false">CARDS_UI_DARK</string>
<string name="pref__app_theme_default" translatable="false">@string/pref__app_theme__cards_ui</string>
<string-array name="pref__app_theme_values">
<item>@string/pref__app_theme__cards_ui</item>
<item>@string/pref__app_theme__cards_ui_dark</item>
</string-array>
</resources>
res/values/strings.xml
<resources>
<string name="app_name">My Application</string>
<string name="app_theme">App Theme</string>
<string name="cards_light">cards light</string>
<string name="cards_dark">cards dark</string>
</resources>
res/xml/pref_general.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- theme -->
<ListPreference
android:defaultValue="@string/pref__app_theme_default"
android:entries="@array/pref__app_theme_entries"
android:entryValues="@array/pref__app_theme_values"
android:key="@string/pref__app_theme"
android:title="@string/app_theme"/>
<EditTextPreference android:key="@string/pref__custom_app_theme"/>
</PreferenceScreen>
SettingsActivity.java
public class SettingsActivity extends PreferenceActivity
{
public interface IOnListPreferenceChosenListener
{
public void onChosenPreference(String key,String entry,String value);
}
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
final EditTextPreference editTextPreference=(EditTextPreference)findPreference(getString(R.string.pref__custom_app_theme));
final ListPreference listPreference=prepareListPreference(this,R.string.pref__app_theme,R.array.pref__app_theme_entries,R.array.pref__app_theme_values,R.string.pref__app_theme_default,new IOnListPreferenceChosenListener()
{
@Override
public void onChosenPreference(final String key,final String entry,final String value)
{
editTextPreference.setTitle(value);
editTextPreference.setSummary(entry);
}
});
editTextPreference.setTitle(listPreference.getValue());
editTextPreference.setSummary(listPreference.getEntry());
}
public static ListPreference prepareListPreference(final PreferenceActivity activity,final int prefKeyId,//
final int entriesId,final int valuesId,final int defaultValueId,final IOnListPreferenceChosenListener listener)
{
final String prefKey=activity.getString(prefKeyId);
@SuppressWarnings("deprecation")
final ListPreference pref=(ListPreference)activity.findPreference(prefKey);
final String[] entries=activity.getResources().getStringArray(entriesId);
final String[] values=activity.getResources().getStringArray(valuesId);
final String defaultValue=activity.getResources().getString(defaultValueId);
final String currentValue=PreferenceManager.getDefaultSharedPreferences(activity).getString(prefKey,defaultValue);
for(int i=0;i<values.length;++i)
{
final String value=values[i];
if(TextUtils.equals(currentValue,value))
{
pref.setSummary(entries[i]);
pref.setValueIndex(i);
break;
}
}
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
{
@Override
public boolean onPreferenceChange(final Preference preference,final Object newValue)
{
final String newValueStr=newValue.toString();
String entryChosen=null;
for(int i=0;i<values.length;++i)
{
final String value=values[i];
if(TextUtils.equals(newValueStr,value))
{
entryChosen=entries[i];
break;
}
}
pref.setSummary(entryChosen);
if(listener!=null)
listener.onChosenPreference(prefKey,entryChosen,newValueStr);
return true;
}
});
return pref;
}
}
Upvotes: 1