Friday, April 29, 2016

How to reference or “find” a PreferenceActivity?

Leave a Comment

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.

1 Answers

Answers 1

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 OnSharedPreferenceChangeListeners or an EventBus.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment