Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference or "find" a PreferenceActivity?

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.

like image 366
Electro-Bunny Avatar asked Apr 20 '16 18:04

Electro-Bunny


People also ask

How do I use Preferencefragment?

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() .

What are Preferences in Android?

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.

How do I set custom preferences on Android?

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.

Where can I find preferences in Android Studio?

Navigate to the app > res > xml > preferences.


1 Answers

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.

like image 112
Jared Rummler Avatar answered Sep 25 '22 18:09

Jared Rummler