Search code examples
javaandroidpreferencefragmentonpreferenceclicklistener

Android OnPreferenceClickListener


I have an Activity that displays a settings menu using a PreferenceFragment. There is a method that passes a list of Beans to the fragment so it can dynamically generate a list of Preferences that I want to act essentially like buttons. I'm trying to use the OnPreferenceClickListener to react to one of the Preferences being clicked, but I need to let the outermost Activity know about this. My code looks like this:

public class PairActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fragment = new SettingsFragment();
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, fragment)
                .commit();
        ...
    }


    public static class SettingsFragment extends PreferenceFragment {
        public void displayBeans(Collection<Bean> beans) {
            ...
            for(Bean bean : beans) {
                Preference pref = new Preference(getActivity());
                pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                    @Override
                    public boolean onPreferenceClick(Preference preference) {
                        // want to let the Activity know something happened
                    }
                });
            }
        }
    }

    ...
}

The comment shows where I want to reach the Activity from, but it's inside of an anonymous class inside a static class... What can I do to solve my issue?


Solution

  • Edit:

    Make your SettingsFragment an inner class of PairActivity:

    public class PairActivity extends Activity {
    
        public class SettingsFragment extends PreferenceFragment {
    
        }
    
    }
    

    Then you can safely reference the activity with PairActivity.this.

    Edit:

    That's a nice answer you linked and it's indeed the proper way to use it like that. I didn't think about it.

    Nevertheless when the fragment is attached to an activity you can reference it using getActivity. A fragment will definitely be attached to an activity if you call this method from inside of a clickListener so it's fine to do this:

    public class PairActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            fragment = new SettingsFragment();
            getFragmentManager().beginTransaction()
                    .replace(android.R.id.content, fragment)
                    .commit();
            ...
        }
    
    
        public static class SettingsFragment extends PreferenceFragment {
            public void displayBeans(Collection<Bean> beans) {
                ...
                for(Bean bean : beans) {
                    Preference pref = new Preference(getActivity());
                    pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                        @Override
                        public boolean onPreferenceClick(Preference preference) {
                            PairActivity pairActivity = (PairActivity) getActivity();
                            // Do something with pairActivity instance
                        }
                    });
                }
            }
        }
    
        ...
    }
    

    You just need to make sure that you don't attach your fragment to another activity as the cast (PairActivity) will throw an exception then.