我的onAttach()方法将上下文分配给侦听器,但是,我的侦听器以某种方式为null。我该如何正确解决这个问题?我希望你能为我提供一些指示代码吗?
选择屏幕类初始化对话框(在本例中为nameDialog):
public class ChooseScreen extends AppCompatActivity {
private Button vsFriend;
private Button vsAndroid;
private NameDialog.NameDialogListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_screen);
vsFriend = findViewById(R.id.vsF);
vsAndroid = findViewById(R.id.vsA);
vsFriend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDialog();
}
});
}
public void openDialog() {
NameDialog nameDialog = new NameDialog();
nameDialog.show(getSupportFragmentManager(), "example");
}
}
带有getTexts接口的NameDialog类:
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 (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement");
}
}
public interface NameDialogListener {
void getTexts(String player1, String player2);
}
}
实现NameDialogListener并覆盖接口方法(getTexts)的游戏类:
public class Game extends AppCompatActivity implements
NameDialog.NameDialogListener {
private TextView player1Name;
private TextView player2Name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
player1Name = findViewById(R.id.player1TextView);
player2Name = findViewById(R.id.player2TextView);
}
@Override
public void getTexts(String player1, String player2) {
player1Name.setText(player1);
player2Name.setText(player2);
}
}
错误:如果我不使用try-catch块,则错误将为NullPointerException,因为listener为null!
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.tictactoe, PID: 30462
java.lang.ClassCastException: com.example.user.tictactoe.ChooseScreen@1a0a489must implement
at com.example.user.tictactoe.NameDialog.onAttach(NameDialog.java:62)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1372)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
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)
当你附加你的片段时,你试图从你的ChoooseScreen Activity
获得一个听众。 Activity
未实现NameDialogListener
,因此您获得了ClassCastException。在您的示例中,您会显示另一个Activity
,确实会实现监听器的游戏,但是您添加Fragment
的任何活动都需要实现监听器才能使用您的onAttach()
代码。
简短回答:如果您想在Fragment
中显示ChooseScreen
,则您的代码需要ChooseScreen
来实施NameDialogListener
。
答案 1 :(得分:0)
onAttach将获取您父项活动的上下文。从ChooseScreen活动打开对话框时,父级是ChooseScreen。接口回调将被赋予ChooseScreen本身。那么你需要做的是用player1Name和player2Name调用Intent。
无论如何,我会为你分享代码。
您的选择屏幕
public class ChooseScreen extends AppCompatActivity implements NameDialog.NameDialogListener {
private Button vsFriend;
private Button vsAndroid;
private NameDialog.NameDialogListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_screen);
vsFriend = findViewById(R.id.vsF);
vsAndroid = findViewById(R.id.vsA);
vsFriend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDialog();
}
});
}
public void openDialog() {
NameDialog nameDialog = new NameDialog();
nameDialog.show(getSupportFragmentManager(), "example");
}
@Override
public void getTexts(String player1, String player2) {
Intent intent = new Intent(this, Game.class);
intent.putExtra("PLAYER_ONE", player1);
intent.putExtra("PLAYER_TWO", player2);
startActivity(intent);
}
}
你的姓名对话
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);
//TODO you can simply use below code and comment listener.getTexts();
// Intent intent = new Intent(NameDialog.this.getActivity(), Game.class);
// intent.putExtra("PLAYER_ONE", player1);
// intent.putExtra("PLAYER_TWO", player2);
// startActivity(intent);
}
});
return builder.create();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (NameDialogListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement");
}
}
public interface NameDialogListener {
void getTexts(String player1, String player2);
}
}
你的游戏
public class Game extends AppCompatActivity
/* implements NameDialog.NameDialogListener*/ {
private TextView player1Name;
private TextView player2Name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
player1Name = findViewById(R.id.player1TextView);
player2Name = findViewById(R.id.player2TextView);
player1Name.setText(
getIntent().getStringExtra("PLAYER_ONE"));
player2Name.setText(
getIntent().getStringExtra("PLAYER_TWO"));
}
// @Override
// public void getTexts(String player1, String player2) {
// }
}
试试这个让我知道......