Ответ 1
Использование
Parent.setSummary("string depending on the selection");
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
работает как шарм и может использоваться независимо от места, где вы изменяете сводку.
В моем приложении Android у меня есть родитель PreferenceScreen
, у которого есть 3 CheckBoxPreferences
как дети.
Когда я нажимаю на родительский экран предпочтения и отображаются 3 флажка, я выбираю один из них, а в элементе Preference.OnPreferenceChangeListener, связанный с флажками, я устанавливаю сводку родительского предпочтения в виде скриншота с помощью:
Parent.setSummary("string depending on the selection")
Дело в том, что, когда я возвращаюсь к родительскому объекту, он не обновляется, даже если внутренне значение соответствующим образом изменилось на значение, установленное.
Есть ли у кого-нибудь идеи относительно этого поведения?
Использование
Parent.setSummary("string depending on the selection");
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
работает как шарм и может использоваться независимо от места, где вы изменяете сводку.
Я обнаружил, что, похоже, это работает, следуя setSummary()
с getListView().invalidate()
Вы можете использовать BaseAdapter.notifyDataSetChanged()
в родительском PreferenceScreen
для обновления UI
. См. Здесь, например, код: Обновить существующий элемент предпочтения в PreferenceActivity после возврата с (под) Экран предпочтений
Это правильный способ
Preference pref = findPreference(getString(R.string.key_of_pref));
PreferenceScreen parent = (PreferenceScreen) sf.findPreference(getString(R.string.key_of_preference_screen));
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean newValueBool = (Boolean) newValue;
parent.setSummary(newValueBool ? "Summary is true" : "Summary is false");
((BaseAdapter) getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
// true to update the state of the Preference with the new value
// in case you want to disallow the change return false
return true;
}
});
Новая настойчивость в отношении фрагментов вместо действий, похоже, делает это сложнее. Маршрут invalidate
, похоже, не работает и не подходит с использованием базового представления. Благодаря решению halxinate, мне удалось это проделать. Для людей, которые являются такими же новыми, как и я для всего этого, вот несколько деталей:
При создании фрагмента настроек сохраните ссылку в своем основном действии, например:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_preferences:
if (getFragmentManager().getBackStackEntryCount() < 1) {
FragmentTransaction trans = getFragmentManager()
.beginTransaction();
// Save a reference to the settings fragment
settingsFrag = new SettingsFragment();
trans.replace(R.id.container, settingsFrag);
trans.addToBackStack(null);
trans.commit();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Затем, когда вы хотите обновить сводки внешнего PreferenceScreen
из OnSharedPreferenceChangeListener
, используйте эту вещь. Обратите внимание, что вам нужно определить ключ в вашем фрагменте xml предпочтений для внешнего PreferenceScreen
(в данном случае android:key="prefs_root"
):
public static void setOuterSummaries(SettingsFragment sf) {
// Set the outer preferences summaries
if (sf == null)
return;
//Code to update the summaries....
// Force the parent screen summaries to update
prefScr = (PreferenceScreen) sf.findPreference("prefs_root");
if (prefScr != null)
((BaseAdapter) prefScr.getRootAdapter()).notifyDataSetChanged();
}
OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
Log.e("L", "Change");
setOuterSummaries(settingsFrag);
}
};
Обратите внимание, что вы можете сохранить ссылку на BaseAdapter
вместо фрагмента настроек, но этот подход кажется более безопасным, если вы думаете об обобщении его на многоэкранную ситуацию или код, который динамически создает содержимое фрагмента.