无法使用 DialogFragment 调用 MainActivity.super.onBackPressed()
Can't invoke MainActivity.super.onBackPressed() using DialogFragment
我有一个通用的 DialogFragment,我在 MainActivity 中将其用于多种不同的用途。
其中之一是在用户按下后退按钮时显示退出应用程序的确认对话框。如果用户点击'yes',我想调用MainActivity.super.onBackPressed()。问题是它不起作用,它只是关闭对话框。
但是,如果我使用 finish() 而不是 MainActivity.super.onBackPressed() 它工作正常,但我知道最好的做法是使用 super.onBackPressed( ) 而不是 finish()。
我试过只使用 super.onBackPressed() 或使用 getActivity(),没有解决。
感谢任何帮助 - 如何从 DialogFragment 正确调用 MainActivity.super.onBackPressed()?
这是我的代码:
public class ConfirmationDialog extends DialogFragment {
// Do nothing by default
private Runnable mConfirm = new Runnable() {
@Override
public void run() {
}
};
// Do nothing by default
private Runnable mCancel = new Runnable() {
@Override
public void run() {
}
};
public void setArgs(String message, String yesButton, String noButton) {
setArgs("", message, yesButton, noButton);
}
public void setArgs(String message, String yesButton) {
setArgs("", message, yesButton, "");
}
public void setArgs(String title, String message, String yesButton, String noButton) {
Bundle args = new Bundle();
args.putString("message", message);
args.putString("title", title);
args.putString("yes_button", yesButton);
args.putString("no_button", noButton);
setArguments(args);
}
public void setConfirm(Runnable confirm) {
mConfirm = confirm;
}
public void setCancel(Runnable cancel) {
mCancel = cancel;
}
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Resources res = getActivity().getResources();
String title = getArguments().getString("title");
String message = getArguments().getString("message");
String yesButton = getArguments().getString("yes_button");
String noButton = getArguments().getString("no_button");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), android.R.style.Theme_Material_Dialog_Alert);
if (!noButton.equals(""))
builder.setNegativeButton(noButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mCancel.run();
}
});
builder.setIcon(R.mipmap.my_launcher)
.setTitle(title.equals("") ? res.getString(R.string.app_name) : title)
.setMessage(message)
.setPositiveButton(yesButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mConfirm.run();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
// If only positive button, center it.
if (noButton.equals("")) {
Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
LinearLayout parent = (LinearLayout) positiveButton.getParent();
LinearLayout.LayoutParams positiveButtonLL = (LinearLayout.LayoutParams) positiveButton.getLayoutParams();
positiveButtonLL.width = ViewGroup.LayoutParams.MATCH_PARENT;
}
return dialog;
}
}
在我的 MainActivity 中:
public void showDialogFragment(DialogFragment newFragment) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
// save transaction to the back stack
ft.addToBackStack("dialog");
newFragment.show(ft, "dialog");
}
@Override
public void onBackPressed() {
ConfirmationDialog dialog = new ConfirmationDialog();
dialog.setArgs(getResources().getString(R.string.exit_app_msg), getResources().getString(R.string.yes), getResources().getString(R.string.no));
Runnable confirm = new Runnable() {
@Override
public void run() {
**// finish();
MainActivity.super.onBackPressed();**
}
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
}
一旦您的对话框显示,它就会获得焦点。然后你的后退键将关闭对话框,你的 activity 再次获得焦点,如果 activity 堆栈中只有一个 activity,再按一次后退键将关闭你的应用程序。这是正常流程。
如果您想退出您的应用:
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
或
// Recommended
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory( Intent.CATEGORY_HOME );
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
在您的 ConfirmationDialog
中试试这个
builder.setIcon(R.mipmap.my_launcher)
.setTitle(title.equals("") ? res.getString(R.string.app_name) : title)
.setMessage(message)
.setPositiveButton(yesButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
mConfirm.run();
}
});
或在您的 activity
@Override
public void onBackPressed() {
ConfirmationDialog dialog = new ConfirmationDialog();
dialog.setArgs(getResources().getString(R.string.exit_app_msg), getResources().getString(R.string.yes), getResources().getString(R.string.no));
Runnable confirm = new Runnable() {
@Override
public void run() {
dialog.dismiss();
MainActivity.super.onBackPressed();
}
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
}
我有一个通用的 DialogFragment,我在 MainActivity 中将其用于多种不同的用途。 其中之一是在用户按下后退按钮时显示退出应用程序的确认对话框。如果用户点击'yes',我想调用MainActivity.super.onBackPressed()。问题是它不起作用,它只是关闭对话框。 但是,如果我使用 finish() 而不是 MainActivity.super.onBackPressed() 它工作正常,但我知道最好的做法是使用 super.onBackPressed( ) 而不是 finish()。 我试过只使用 super.onBackPressed() 或使用 getActivity(),没有解决。
感谢任何帮助 - 如何从 DialogFragment 正确调用 MainActivity.super.onBackPressed()?
这是我的代码:
public class ConfirmationDialog extends DialogFragment {
// Do nothing by default
private Runnable mConfirm = new Runnable() {
@Override
public void run() {
}
};
// Do nothing by default
private Runnable mCancel = new Runnable() {
@Override
public void run() {
}
};
public void setArgs(String message, String yesButton, String noButton) {
setArgs("", message, yesButton, noButton);
}
public void setArgs(String message, String yesButton) {
setArgs("", message, yesButton, "");
}
public void setArgs(String title, String message, String yesButton, String noButton) {
Bundle args = new Bundle();
args.putString("message", message);
args.putString("title", title);
args.putString("yes_button", yesButton);
args.putString("no_button", noButton);
setArguments(args);
}
public void setConfirm(Runnable confirm) {
mConfirm = confirm;
}
public void setCancel(Runnable cancel) {
mCancel = cancel;
}
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Resources res = getActivity().getResources();
String title = getArguments().getString("title");
String message = getArguments().getString("message");
String yesButton = getArguments().getString("yes_button");
String noButton = getArguments().getString("no_button");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), android.R.style.Theme_Material_Dialog_Alert);
if (!noButton.equals(""))
builder.setNegativeButton(noButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mCancel.run();
}
});
builder.setIcon(R.mipmap.my_launcher)
.setTitle(title.equals("") ? res.getString(R.string.app_name) : title)
.setMessage(message)
.setPositiveButton(yesButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mConfirm.run();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
// If only positive button, center it.
if (noButton.equals("")) {
Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
LinearLayout parent = (LinearLayout) positiveButton.getParent();
LinearLayout.LayoutParams positiveButtonLL = (LinearLayout.LayoutParams) positiveButton.getLayoutParams();
positiveButtonLL.width = ViewGroup.LayoutParams.MATCH_PARENT;
}
return dialog;
}
}
在我的 MainActivity 中:
public void showDialogFragment(DialogFragment newFragment) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
// save transaction to the back stack
ft.addToBackStack("dialog");
newFragment.show(ft, "dialog");
}
@Override
public void onBackPressed() {
ConfirmationDialog dialog = new ConfirmationDialog();
dialog.setArgs(getResources().getString(R.string.exit_app_msg), getResources().getString(R.string.yes), getResources().getString(R.string.no));
Runnable confirm = new Runnable() {
@Override
public void run() {
**// finish();
MainActivity.super.onBackPressed();**
}
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
}
一旦您的对话框显示,它就会获得焦点。然后你的后退键将关闭对话框,你的 activity 再次获得焦点,如果 activity 堆栈中只有一个 activity,再按一次后退键将关闭你的应用程序。这是正常流程。
如果您想退出您的应用:
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
或
// Recommended
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory( Intent.CATEGORY_HOME );
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
在您的 ConfirmationDialog
builder.setIcon(R.mipmap.my_launcher)
.setTitle(title.equals("") ? res.getString(R.string.app_name) : title)
.setMessage(message)
.setPositiveButton(yesButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
mConfirm.run();
}
});
或在您的 activity
@Override
public void onBackPressed() {
ConfirmationDialog dialog = new ConfirmationDialog();
dialog.setArgs(getResources().getString(R.string.exit_app_msg), getResources().getString(R.string.yes), getResources().getString(R.string.no));
Runnable confirm = new Runnable() {
@Override
public void run() {
dialog.dismiss();
MainActivity.super.onBackPressed();
}
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
}