0

我想知道如何实现这个 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)
4

2 回答 2

1

你确定你得到一个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)

重要的是打电话给super.onDetach()你正在停止生命周期FragmentActivity可能受到影响(在我的理论中)。

@Override
public void onDetach()
{
     mListener = null;
     super.onDetach()
}
于 2013-02-21T02:36:07.633 回答
0

我在你的帮助下弄清楚了,查看了崩溃日志,它说“没有调用 super.detach,所以我把它放在了 on detach 中,并且成功了。

    @Override
public void onDetach() {
    super.onDetach(); <--------
    mListener = null;
}
于 2013-02-21T19:12:33.987 回答