如何实现DialogFragment

时间:2013-02-21 02:30:19

标签: android

我想知道如何实现这个DialogFragment类:

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

我已经在片段中的类中实现了DialogListener,如下所示:

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

    }

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

并出现对话框,但是当我单击ON或CANCEL时会抛出IllegalArgumentException

这是日志:

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)

2 个答案:

答案 0 :(得分:1)

您确定收到了IllegalArgumentException吗?

基于您的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)

重要的是致电super.onDetach()您要停止Fragment的生命周期,Activity可能会受到影响(在我的理论中)。

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

答案 1 :(得分:0)

我在你的帮助下想出来,看着崩溃日志,它说“没有打电话给super.detach,所以我把它放在分离中,并且bam工作。

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