Search code examples
androidandroid-fragmentsandroid-listfragmentandroid-dialogfragment

Calling setTitle() on a DialogFragment from a ListFragment


I am trying to set the title of a DialogFragment from the onActivityCreated method of a Fragment extending ListFragment.

public void onActivityCreated(Bundle savedState) {
    super.onActivityCreated(savedState);
    ListView lv = this.getListView();
    lv.setOnItemLongClickListener(new OnItemLongClickListener() {

        public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                int pos, long id) {

            android.app.FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager
                    .beginTransaction();
            RatingDialogFragment newFragment = new RatingDialogFragment();
            newFragment.getDialog().setTitle("String");
            fragmentTransaction.add(newFragment, "dialog");
            newFragment.show(fragmentTransaction, "dialog");

            return true;
        }
    });
}

This produces a null pointer exception because the DialogFragment's mDialog is still null.

See: DialogFragment.getDialog returns null

Any ideas on how to fix this?


Solution

  • One possible way to fix this is to let the Fragment being created decide when it's safe to set its title.

    For example, you could pass the title in the constructor and keep it in a member variable.

    RatingDialogFragment newFragment = new RatingDialogFragment("String");
    

    Then in your RatingDialogFragment:

    ...
    public RatingDialogFragment(String title) {
       mTitle = title;
    }
    ...
    

    Somewhere in your RatingDialogFragment lifecycle, when it's safe to do so, actually set the title.

    ...
    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Set title for this dialog
            getDialog().setTitle(mTitle);
        }
    

    Edit: It is worth noting that although this works in this particular case, a better general approach is to use Fragment's ability to receive arguments via the setArguments() and getArguments() methods. This allows you to keep the default empty constructor there so that your fragment can be instantiated by the framework correctly (eg if you were introducing your Fragment via XML). An example can be found here.

    From the documentation:

    Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle) and later retrieved by the Fragment with getArguments().