听众是空的

时间:2018-06-13 02:50:01

标签: android listener

我100%肯定在onCreate之前调用了ontach方法,所以我的监听器如何为空?我该如何解决?基本上,如果我可以从NameDialog获取值,我将调用另一个实现NameDialogListener接口的活动(比如游戏),这样我就可以在游戏活动中覆盖getTexts方法。

    public class NameDialog extends AppCompatDialogFragment {
    private EditText firstPlayer;
    private EditText secondPlayer;
    private NameDialogListener listener;


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        LayoutInflater inflater = getActivity().getLayoutInflater();
        final View view = inflater.inflate(R.layout.layout_dialog, null);

        firstPlayer = view.findViewById(R.id.edit_player1);
        secondPlayer = view.findViewById(R.id.edit_player2);

        builder.setView(view)
                .setTitle("Names")
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String player1 = firstPlayer.getText().toString();
                        String player2 = secondPlayer.getText().toString();
                        listener.getTexts(player1, player2);
                        // Intent intent = new Intent(NameDialog.this.getActivity(), Game.class);
                        // startActivity(intent);


                    }
                });

        return builder.create();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
           listener = (NameDialogListener) context;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public interface NameDialogListener {
        void getTexts(String player1, String player2);
    }
}

错误 - 日志:

/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.anil.tictactoe, PID: 6009
                  **java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.anil.tictactoe.NameDialog$NameDialogListener.getTexts(java.lang.String, java.lang.String)' on a null object reference
                      at com.example.anil.tictactoe.NameDialog$1.onClick(NameDialog.java:43)**
                      at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:175)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6776)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

4 个答案:

答案 0 :(得分:0)

1)从问题来看,似乎在实例化Dialog的活动中没有正确实现接口。

2)如果接口已正确实现,您可以尝试在对话框的构造函数中传递活动的实例,如此

NameDialog(Activity activity){
     listener = (NameDialogListener) activity;
}

3)(不推荐)您也可以通过覆盖 onAttach(活动活动)来尝试快速修复(弃用方法) onAttach(上下文上下文)。基本上代码看起来像

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
       listener = (NameDialogListener) activity;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

答案 1 :(得分:0)

通过在匿名上下文中引用listener,Java将创建要在匿名类中使用的成员的最终副本。这意味着如果listener发生更改,则最终副本不会观察到更改。

为了解决这个问题,请使用OnClickListener的具体类并将侦听器传递给它。这样可以避免创建最终副本。

答案 2 :(得分:0)

必须抛出一个异常,尝试记录它,或者你可以干它或者使用调试器来查看在onCreate之前无法调用onDetach的事情

您使用的上下文是匿名的,您应该使用具体的上下文或将其强制转换为实现接口的位置

答案 3 :(得分:0)

问题可能在显示DialogFragment的代码中。 显示DialogFrament的好方法是

  

new NameDialog()。show(getSupportFragmentManager()," my_name_dialog");

这将调用onAttach来获取上下文。

您还应该更改onAttach,如下所示。因为你不需要其他人使用这个DialogFragment来错过你活动界面的实现。

     @Override public void onAttach(Context context) {
         super.onAttach(context);
         if (context instanceof NameDialogListener) {
             mListener = (NameDialogListener) context;
         } else {
             throw new RuntimeException(context.toString()
                     + " must implement NameDialogListener");
         } 
     }