user1848850
user1848850

Reputation: 463

How to implement DialogFragment

i was wondering how to implement This DialogFragment class:

public class MyDialogFragment extends DialogFragment {

    private static final String ARG_LISTENER_TYPE = "listenerType";
    private DialogListener mListener;

    static enum ListenerType {
        ACTIVITY, FRAGMENT
    }

    public interface DialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    public static MyDialogFragment newInstance(DialogListener listener) {
        final MyDialogFragment instance;

        if (listener instanceof Activity) {
            instance = createInstance(ListenerType.ACTIVITY);
        } else if (listener instanceof Fragment) {
            instance = createInstance(ListenerType.FRAGMENT);
            instance.setTargetFragment((Fragment) listener, 0);
        } else {
            throw new IllegalArgumentException(listener.getClass() + " must be either an Activity or a Fragment");
        }

        return instance;
    }

    private static MyDialogFragment createInstance(ListenerType type) {
        MyDialogFragment fragment = new MyDialogFragment();

        Bundle args = new Bundle();
        args.putSerializable(ARG_LISTENER_TYPE, type);
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // TODO: Create your dialog here

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.app_name);
        builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mListener.onDialogPositiveClick(MyDialogFragment.this);
            }
        });
        builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mListener.onDialogNegativeClick(MyDialogFragment.this);
            }
        });

        return builder.create();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Find out how to get the DialogListener instance to send the callback
        // events to
        Bundle args = getArguments();
        ListenerType listenerType = (ListenerType) args.getSerializable(ARG_LISTENER_TYPE);

        switch (listenerType) {
        case ACTIVITY: {
            // Send callback events to the hosting activity
            mListener = (DialogListener) activity;
            break;
        }
        case FRAGMENT: {
            // Send callback events to the "target" fragment
            mListener = (DialogListener) getTargetFragment();
            break;
        }
        }
    }

    @Override
    public void onDetach() {
        mListener = null;
    }
}

i have implemented the DialogListener from the class in my fragment like this:

public class MyFragment extends Fragment implements DialogListener

    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // TODO Auto-generated method stub

    }

and:

MyDialogFragment dialogFragment = MyDialogFragment.newInstance(MyFragment.this);
dialogFragment.show(getFragmentManager(), getTag());

and the dialog box appears, but when i click ON or CANCEL it throws a IllegalArgumentException

Here's the Log:

02-20 22:02:57.022: E/AndroidRuntime(1997): FATAL EXCEPTION: main
02-20 22:02:57.022: E/AndroidRuntime(1997): android.app.SuperNotCalledException: Fragment MyDialogFragment{b57064f0 #1} did not call through to super.onDetach()
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:992)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1123)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.BackStackRecord.run(BackStackRecord.java:592)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.os.Handler.handleCallback(Handler.java:605)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.os.Looper.loop(Looper.java:137)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.ActivityThread.main(ActivityThread.java:4424)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at java.lang.reflect.Method.invokeNative(Native Method)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at java.lang.reflect.Method.invoke(Method.java:511)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 1552

Answers (2)

Glenn
Glenn

Reputation: 12809

Are you sure that you're getting an IllegalArgumentException?

Base on your stacktrace

02-20 22:02:57.022: E/AndroidRuntime(1997): FATAL EXCEPTION: main
02-20 22:02:57.022: E/AndroidRuntime(1997): android.app.SuperNotCalledException: Fragment MyDialogFragment{b57064f0 #1} did not call through to super.onDetach()
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:992)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1123)
02-20 22:02:57.022: E/AndroidRuntime(1997):     at android.app.BackStackRecord.run(BackStackRecord.java:592)

It is important to call super.onDetach() you're stopping the lifecycle of Fragment and Activity might be affected (In my theory).

@Override
public void onDetach()
{
     mListener = null;
     super.onDetach()
}

Upvotes: 1

user1848850
user1848850

Reputation: 463

I figured it out with your help, looking at the crash log, it said "didn't call through to super.detach, so i put that in the on detach, and bam it worked.

    @Override
public void onDetach() {
    super.onDetach(); <--------
    mListener = null;
}

Upvotes: 0

Related Questions