我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)
答案 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");
}
}