Search code examples
androidandroid-fragmentsactionbarsherlockandroid-support-library

Using an Android-Support-Fragment in Preference Headers


My app supports Android versions up to Android 2.2, that's why in general I'm using support Fragments (i.e. SherlockFragments).

My preferences are build to use headers when API > 11 and the traditional preferences when lower. Now I have implemented a (support) Fragment with a logic that cannot be replicated with preferences only. On older Android version it will be launched within a simple SherlockFragmentActivity but on newer versions it is supposed to be launched from a header.

This is the problem: Headers expect native fragments. That's why on newer versions the preferences crash. Is there a possibility to circumvent this limitation?

I'm thinking of the following possibilities:

  • Wrap the support Fragment within a native Fragment. Can I do that? If yes, how?
  • Capture the click event from the header and launch the fragment myself on newer versions. Can I add simple preferences besides headers?

Solution

  • Here's my solution:

    I created a native Fragment that wraps my SherlockFragment.

    public class HelperFragment extends ListFragment {
        MyFragment cp;
    
        public HelperFragment() {
            cp = new MyFragment();
        }
    }
    

    The overwritten calls like onCreateView() need to be forwarded but some need special treatment. Instead of getActivity() in MyFragment I used the following construct:

    private Activity activity;
    
    @Override
    public void onAttach(final Activity activity) {
        this.activity = activity;
        super.onAttach(activity);
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        activity = null;
    }
    
    public void setActivity(final Activity activity) {
        this.activity = activity;
    }
    

    The HelperFragment calls the setter when it gets attached and detached and if MyFragment gets attached the usual way it works as usual.

    In my case the HelperFragment is also a ListFragment so calls to getListView() need to be redirected. I solved it by overwritting getListView() in MyFragment:

    private ListView listView;
    @Override
    public ListView getListView() {
        if (listView != null) {
            return listView;
        } else {
            return super.getListView();
        }
    }
    
    public void setListView(final ListView listView) {
        this.listView = listView;
    }
    

    and called setListView() in HelperFragment's onActivityCreated() method. Depending on usage there will be other methods that need special treatment but the concept should be clear.