I have legacy code which extends PreferenceActivity with a subclass called "Preferences". The PreferenceActivity is invoked as follows:
Intent intent = new Intent(this, Preferences.class);
this.startActivity(intent);
The OnSharedPreferenceChangeListener exists in a another fragment (not the PreferenceActivity subclass) but needs a reference to the PreferenceActivity in order to modify attributes of a custom preference/control similar to the following:
pref = (CheckBoxPreference) prefActivity.findPreference(res.getString(R.string.keyAccount));
pref.setSummary("something");
where "prefActivity" is the reference to the PreferenceActivity. Can anyone suggest how to save a reference to the PreferenceActivity when it is created or otherwise locate the PreferenceActivity when needed?
EDIT: Including the grossly oversimplified code to hopefully help show hierarchies and clarify.
The FragmentActivity CPActivity instantiates CPFragment and on demand (a button press) creates an Intent to fire off a PreferenceActivity subclass (called "Preferences").
public class CPActivity extends FragmentActivity
{
public static CPActivity inst;
private CPFragment mFragmentCP;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
inst = this;
mFragmentCP = new CPFragment();
}
public void onSettingsButtonPressed() {
// Bring up the Preferences menu
Intent intent = new Intent(this, Preferences.class);
this.startActivity(intent);
}
}
CPFragment is our shared preference listener (among other things). It is in this code, where we'd like to modify a custom preference control/entry (that is, not the preference value itself, rather attributes on the preference control, e.g. a CheckBoxPreference). We'd like to do it here because this is where the pertinent data is calculated.
public class CPFragment extends Fragment implements OnSharedPreferenceChangeListener
{
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// In response to preference changes, we want to modify the PreferenceActivity controls.
// So it seems we would need a reference to the PreferenceActivity subclass "Preferences
}
}
And finally, the PreferenceActivity subclass "Preferences" does little more than bring up the Settings view.
public class Preferences extends PreferenceActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences_cp);
}
}
As I mentioned, we'd prefer to be able to modify the Custom Preference in CPFragment (as opposed to the PreferenceActivity). Therefore I was looking for some way of locating the PreferenceActivity while responding as onSharedPreferenceChangeListener in CPFragment.
If I understand your question correctly, you have an Activity
named Preferences
which extends
PreferenceActivity
. You also have a Fragment
that has registered an OnSharedPreferenceChangeListener
. You need to update the UI in your Preferences
Activity
but you are not sure how to accomplish this.
Is the Fragment
attached to the Preferences
Activity
? If it is, then you should be able to do the following in your Fragment
:
if (getActivity() instanceof Preferences) {
Preferences activity = (Preferences) getActivity();
CheckBoxPreference pref = (CheckBoxPreference) activity.findPreference(getString(R.string.keyAccount));
pref.setSummary("something");
}
Another approach:
You can also register an OnSharedPreferenceChangeListener
in your Preferences
Activity
and you will get notified when the preference changes. Example:
public class Preferences extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
/* ... */
@Override protected void onStart() {
super.onStart();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(getString(R.string.keyAccount))) {
CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
pref.setSummary("something");
}
}
@Override protected void onPause() {
super.onPause();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
/* ... */
}
Some things to consider based on your edited answer:
1) Never create a static
reference to your Activity
. public static CPActivity inst;
. This can lead to memory leaks.
2) Consider moving code in your Preferences
Activity
to a PreferenceFragment
.
3) It is still unclear what you are trying to achieve. Is the CheckBoxPreference
that you want to modify in your CPFragment
or the Preferences
Activity
?
4) You should still consider using two OnSharedPreferenceChangeListener
s or an EventBus.