我一直试图解决这个问题,但我无法做到。我一直在读一本书,
Android 6 for Programmers_ An App-Driven Approach (3rd ed.)
我已经按照每一步,但仍然会返回错误。本章是关于制作应用程序“FlagQuiz App”。此外,应用程序工作正常,但需要显示AlertDialog时崩溃。 MainActivityFragment.java具有以下代码,并且在定义new DialogFragment()
的地方,它会给出一个红色下划线错误:
"Fragments should be static such that they can be re-instantiated by the system, and anonymous classes are not static".
实际上,该方法是OnClickListener
的匿名方法。这是返回此错误的代码。
// called when a guess Button is touched
private OnClickListener guessButtonListener = new OnClickListener() {
@Override
public void onClick(View v) {
Button guessButton = ((Button) v);//The method receives the clicked Button as parameter v
String guess = guessButton.getText().toString();
String answer = getCountryName(correctAnswer);
++totalGuesses;// increment number of guesses the user has made
if (guess.equals(answer)){ // if the guess is correct
++correctAnswers;
// display correct answer in green text
answerTextView.setText(answer + "!");
answerTextView.setTextColor(getResources().getColor(R.color.correct_answer, getContext().getTheme()));
disableButtons(); // disable all guess Buttons
// if the user has correctly identified FLAGS_IN_QUIZ flags
if (correctAnswers == FLAGS_IN_QUIZ) {
// DialogFragment to display quiz stats and start new quiz
DialogFragment quizResults = new DialogFragment() {
// create an AlertDialog and return it
@Override
public Dialog onCreateDialog(Bundle bundle) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());//AlertDialog.Builder to configure and create an AlertDialog for showing the quiz results, then returns it.
builder.setMessage(getString(R.string.results, totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz" Button
builder.setPositiveButton(R.string.reset_quiz, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
resetQuiz();
}
}
);
return builder.create(); // return the AlertDialog
}
};
// use FragmentManager to display the DialogFragment
quizResults.setCancelable(false);
quizResults.show(getFragmentManager(), "quiz results");
} else { // answer is correct but quiz is not over - load the next flag after a 2-second delay
handler.postDelayed(new Runnable() {
@Override
public void run() {
animate(true);// animate the flag off the screen
}
}, 2000);// 2000 milliseconds for 2-second delay
}
}
我的错误日志是:
FATALEXCEPTION:main
Process: com.ahsan.a47_dietel_flagquizapp, PID: 3089
java.lang.IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state.
这个问题已经解决了。您需要做的就是删除DialogFragment匿名类,并在onClickListener之外定义此静态类:
public static class MyDialogFragment extends DialogFragment {
public MyDialogFragment(){} // end constructor
// create an AlertDialog and return it
@Override
public Dialog onCreateDialog(Bundle bundle) {
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setMessage(getString(R.string.results, totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz" Button
builder.setPositiveButton(R.string.reset_quiz, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
quizFragment().resetQuiz();
} // end onClick
}
);
return builder.create(); // return the AlertDialog
} // end onCreateDialog
private MainActivityFragment quizFragment (){
return (MainActivityFragment) getFragmentManager().findFragmentById(R.id.quizFragment);
}}
然后你创建一个MyDialogFragment的实例,其中DialogFragment匿名类是这样的:
MyDialogFragment quizResults = new MyDialogFragment();
一切都会很好,因为我已经多次测试过了。