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.
Use PreferenceFragmentCompat to programatically handle preferences. To load the settings into the fragment, load the preferences in the onCreatePreferences() method. To get an instance of a preference, search for a preference using its key through the PreferenceManager within onCreateView() .
Preferences in Android are used to keep track of application and user preferences. In our case, we can modify the SharedPreference instance in our case using the edit() and use the putInt(String key, int newVal) We increased the count for our application that presist beyond the application and displayed accordingly.
In your XML you have to declare the root element as android:id="@android:id/widget_frame , and then declare TextView as android:title and android:summary . You can then declare other elements you want to appear in the layout.
Navigate to the app > res > xml > preferences.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With