0

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)
3
  • 1
    Post the crash log. Also, why are you passing the dialog into your DialogListener interface methods? Commented Feb 21, 2013 at 3:07
  • 1
    Use eclipse to set an exception breakpoint on IllegalArgumentException. (Run menu, select Add Java Exception Breakpoint...). Is it the getTargetFragment() method that's throwing an exception? Commented Feb 21, 2013 at 3:17
  • dymmeh, please look at this link i'm just trying to learn how to do dialogs properly and i stumbled on that link and was trying to figure out what they're doing. i'm still a noob, so i'm not sure why they are passing the dialog into the DialogListener interface methods, if u know why i'd love to know lol Commented Feb 21, 2013 at 19:14

2 Answers 2

1

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()
}
Sign up to request clarification or add additional context in comments.

1 Comment

by the way, when i tried to use getActivity() insteads of this it said "The method newInstance(MyDialogFragment.DialogListener) in the type MyDialogFragment is not applicable for the arguments (Activity)"
0

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.