android - 处理dialogFragment按钮点击

时间:2017-09-01 12:09:34

标签: android fragment android-dialogfragment

我的应用程序中有Activity,里面有很少的碎片。其中一个片段有一个DialogFragment,它通过按钮点击调用。 DialogFragment有3个按钮 - 正面,负面和中性。

public class CompanyNotConnectedToSRDialog extends DialogFragment {

    public static final String TAG = CompanyNotConnectedToSRDialog.class.getSimpleName();

    private NotConnectedDialogListener mNotConnectedDialogListener;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity(), R.style.DefaultAlertDialogTheme)
                .setTitle("Register")
                .setMessage("Do you really want to register?")
                .setNeutralButton("Skip", (dialog1, which) -> {
                    mNotConnectedDialogListener.onSkipBtnNotConnectedDialogPressed();
                })
                .setNegativeButton("Cancel", null)
                .setPositiveButton("Register", (dialog12, which) -> {
                    mNotConnectedDialogListener.onSendBtnNotConnectedDialogPressed();
                })
                .create();
    }


    public interface NotConnectedDialogListener {
        void onSkipBtnNotConnectedDialogPressed();
        void onSendBtnNotConnectedDialogPressed();
    }

    public void setListener(NotConnectedDialogListener listener) {
        this.mNotConnectedDialogListener = listener;
    }

正如你所看到的,我创建了一个公共接口,它包含两个方法,用于我的跳过和注册按钮(取消按钮监听器为空,因此它并不重要)和此侦听器的Setter。 然后我在我的片段中实现了这个接口,它调用了这个dialogFragment,我覆盖了方法并调用了dialogFragment,如下所示:

if (mNotConnectedDialog == null) {
            mNotConnectedDialog = new CompanyNotConnectedToSRDialog();
            mNotConnectedDialog.setListener(this);
            mNotConnectedDialog.show(getActivity().getFragmentManager(), CompanyNotConnectedToSRDialog.TAG);
        } else {
            mNotConnectedDialog.show(mActivity.getFragmentManager(), CompanyNotConnectedToSRDialog.TAG);
            mNotConnectedDialog.setListener(this);
        }

问题是如果我按下父片段中的按钮以显示DialogFragment,旋转屏幕并按下DialogFragment中的任何按钮,我得到NullPointerException,因为我的监听器为空。

java.lang.NullPointerException: Attempt to invoke interface method 'void com.myapp.ui.object.create.dialogs.CompanyNotConnectedToSRDialog$NotConnectedDialogListener.onSendBtnNotConnectedDialogPressed()' on a null object reference

at com.myapp.ui.object.create.dialogs.CompanyNotConnectedToSRDialog.lambda$onCreateDialog$1(CompanyNotConnectedToSRDialog.java:31)

如果此解决方案出错,如何处理这些点击并设置侦听器?

PS:请不要告诉我android:configChanges

2 个答案:

答案 0 :(得分:1)

是的,在方向更改后,您的侦听器为空。回调活动最容易:

public static class DialogFragmentA extends DialogFragment {

    // Container Activity must implement this interface
    public interface NotConnectedDialogListener {
        public void onX();
    }

    NotConnectedDialogListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (NotConnectedDialogListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement NotConnectedDialogListener");
        }
    }
    ...
}

现在您可以在对话框中的任何位置调用mListener.onX等,也可以在方向更改后调用。您的容器Activity必须实现该接口,并将接收方法调用。

https://developer.android.com/guide/components/fragments.html#EventCallbacks

答案 1 :(得分:1)

因此当前解决方案不起作用,因为当您旋转对话框片段时会被销毁并重新创建。所以不调用setListener。解决方案取决于您的侦听器是活动还是其他片段。

如果是活动,您可以在DialogFragment中覆盖onAttach并在那里设置监听器。如果您的侦听器是片段,那么在OnCreateDialog方法中,您可以通过标记查看片段并以此方式设置侦听器。例如。

Fragment listenerFragment = getActivity().getSupportFragmentManager().findFragmentByTag(getString(R.string.your_listener_fragment_tag));

if( listenerFragment instanceOf NotConnectedDialogListener ) {
    listener = (NotConnectedDialogListener) listenerFragment;
} else {
    //Handle what to do if you don't have a listener here. Maybe dismiss the dialog. 
}