在关闭应用程序之前处理最后一次后退点击的最正确方法是什么
What is the most proper way to handle last back click before closing an app
我正在尝试执行确认消息以退出我的应用程序。我需要这个,因为有人可能不小心点击后退按钮不止一次,这将关闭应用程序,如果内存不足,它会在之后被杀死,因为现在它不在前台。
我尝试了不同的方法,但有些方法需要大量检查,有些则根本行不通。
我尝试使用 onKeyDown
事件,onBackPressed
...
问题是因为我不仅要处理活动,还要处理嵌套片段(活动内部)。
我需要在退出前处理最后一次按下后退的点击,所以这意味着当前 activity 的所有片段都必须从堆栈中弹出,而不是 activity 也必须弹出,如果这不是最后一个 activity 对前面的 activity 做同样的事情,直到这不是最后一个 activity 并且所有片段都在其中弹出。
我该如何实施?我曾尝试使用 backstack 来做到这一点,但不幸的是没有成功。
请建议什么是处理此类事件的最佳方法。我想有一种简单的方法可以做到这一点。
基本上覆盖 Main Activity 中的 onBackPressed
() 并避免在用户选择 [=19= 时调用父 super.onBackPressed()
] 退出应用程序。
代码建议:
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exiting app?")
.setPositiveButton("Yes", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// user really do want to exit
MainActivity.super.onBackPressed();
}
}).create().show();
// If negative, show a Fragment or do nothing
}
我不确定,但我认为您可以使用一个整数来计算您的片段数,在添加新片段时增加它并在每次向后按时减少它。可能是这样的:
@Override public void onBackPressed() {
if( fragCount > 0) {
--fragCount;
super.onBackPressed();
return;
}
new AlertDialog.Builder(this) .setTitle("Exiting app?") .setPositiveButton("Yes", new OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { // user really do want to exit
MainActivity.super.onBackPressed(); } }).create().show();
}
注意:很抱歉我在 phone.
上输入错误
感谢大家的解答和建议。
我通过在堆栈中使用片段计数达到了预期的结果。
至于我的 Main Activity 将是第一个 activity 和退出前的最后一个,我可以覆盖其中的 onBackPressed
方法。
所以解决方法很简单。
public class MainActivity extends BaseSingleFragmentActivity {
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.title_exit_message)
.setMessage(R.string.message_exit)
.setPositiveButton(R.string.button_text_yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity.super.onBackPressed();
}
})
.setNegativeButton(R.string.button_text_no, null)
.show();
} else {
MainActivity.super.onBackPressed();
}
}
}
所以这只有在你的 activity 在 Activity Stack 中最后才有效,所以你必须在你的启动器 activity 中覆盖它,而不是在某些基础 activity class 或其他。
我的想法有了一点改进。
package com.crosp.solutions.qrcodereader.dialogs;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import com.crosp.solutions.qrcodereader.R;
import com.crosp.solutions.qrcodereader.constants.FragmentConstants;
/**
* Created by crosp on 7/9/15.
*/
public class ConfirmationDialog extends DialogFragment implements DialogInterface.OnClickListener {
private OnConfirmDialogClickListener mOnConfirmDialogListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOnConfirmDialogListener = (OnConfirmDialogClickListener) activity;
} catch (ClassCastException ex) {
Log.e(getString(R.string.error_tag), "Activty has to implement " + OnConfirmDialogClickListener.class.getSimpleName() + " interface");
}
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setPositiveButton(R.string.button_text_yes, this)
.setNegativeButton(R.string.button_text_no, this);
Bundle bundle = getArguments();
String message = getString(R.string.message_exit);
String title = getString(R.string.title_exit_message);
int iconId = android.R.drawable.ic_dialog_alert;
if (bundle != null) {
String argumentMessage = bundle.getString(FragmentConstants.Arguments.DIALOG_MESSAGE_ARGUMENT);
String argumentTitle = bundle.getString(FragmentConstants.Arguments.DIALOG_TITLE_ARGUMENT);
int argumentIconId = bundle.getInt(FragmentConstants.Arguments.DIALOG_ICON_ID_ARGUMENT);
message = argumentMessage != null ? argumentMessage : message;
title = argumentTitle != null ? argumentTitle : title;
iconId = argumentIconId != 0 ? argumentIconId : iconId;
}
builder.setIcon(iconId);
builder.setMessage(message);
builder.setTitle(title);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
mOnConfirmDialogListener.onConfirmClick();
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
mOnConfirmDialogListener.onCancelClick();
}
}
public interface OnConfirmDialogClickListener {
void onConfirmClick();
void onCancelClick();
}
}
并且在activity
public class MainActivity extends BaseSingleFragmentActivity implements ExitConfirmDialogFactory.OnExitDialogClickListener {
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
Bundle arguments = new Bundle();
if(mExitDialog==null) {
arguments.putInt(FragmentConstants.Arguments.DIALOG_ICON_ID_ARGUMENT, android.R.drawable.ic_dialog_alert);
arguments.putString(FragmentConstants.Arguments.DIALOG_MESSAGE_ARGUMENT, getString(R.string.message_exit));
arguments.putString(FragmentConstants.Arguments.DIALOG_TITLE_ARGUMENT, getString(R.string.title_exit_message));
DialogFragment exitDialog = new ConfirmationDialog();
exitDialog.setArguments(arguments);
mExitDialog = exitDialog;
}
mExitDialog.show(getSupportFragmentManager(),FragmentConstants.Tags.EXIT_DIALOG_TAG);
} else {
super.onBackPressed();
}
}
@Override
public void onConfirmClick() {
super.onBackPressed();
}
@Override
public void onCancelClick() {
}
我正在尝试执行确认消息以退出我的应用程序。我需要这个,因为有人可能不小心点击后退按钮不止一次,这将关闭应用程序,如果内存不足,它会在之后被杀死,因为现在它不在前台。
我尝试了不同的方法,但有些方法需要大量检查,有些则根本行不通。
我尝试使用 onKeyDown
事件,onBackPressed
...
问题是因为我不仅要处理活动,还要处理嵌套片段(活动内部)。
我需要在退出前处理最后一次按下后退的点击,所以这意味着当前 activity 的所有片段都必须从堆栈中弹出,而不是 activity 也必须弹出,如果这不是最后一个 activity 对前面的 activity 做同样的事情,直到这不是最后一个 activity 并且所有片段都在其中弹出。
我该如何实施?我曾尝试使用 backstack 来做到这一点,但不幸的是没有成功。
请建议什么是处理此类事件的最佳方法。我想有一种简单的方法可以做到这一点。
基本上覆盖 Main Activity 中的 onBackPressed
() 并避免在用户选择 [=19= 时调用父 super.onBackPressed()
] 退出应用程序。
代码建议:
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exiting app?")
.setPositiveButton("Yes", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// user really do want to exit
MainActivity.super.onBackPressed();
}
}).create().show();
// If negative, show a Fragment or do nothing
}
我不确定,但我认为您可以使用一个整数来计算您的片段数,在添加新片段时增加它并在每次向后按时减少它。可能是这样的:
@Override public void onBackPressed() {
if( fragCount > 0) {
--fragCount;
super.onBackPressed();
return;
}
new AlertDialog.Builder(this) .setTitle("Exiting app?") .setPositiveButton("Yes", new OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { // user really do want to exit
MainActivity.super.onBackPressed(); } }).create().show();
}
注意:很抱歉我在 phone.
上输入错误感谢大家的解答和建议。
我通过在堆栈中使用片段计数达到了预期的结果。
至于我的 Main Activity 将是第一个 activity 和退出前的最后一个,我可以覆盖其中的 onBackPressed
方法。
所以解决方法很简单。
public class MainActivity extends BaseSingleFragmentActivity {
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.title_exit_message)
.setMessage(R.string.message_exit)
.setPositiveButton(R.string.button_text_yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity.super.onBackPressed();
}
})
.setNegativeButton(R.string.button_text_no, null)
.show();
} else {
MainActivity.super.onBackPressed();
}
}
}
所以这只有在你的 activity 在 Activity Stack 中最后才有效,所以你必须在你的启动器 activity 中覆盖它,而不是在某些基础 activity class 或其他。
我的想法有了一点改进。
package com.crosp.solutions.qrcodereader.dialogs;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import com.crosp.solutions.qrcodereader.R;
import com.crosp.solutions.qrcodereader.constants.FragmentConstants;
/**
* Created by crosp on 7/9/15.
*/
public class ConfirmationDialog extends DialogFragment implements DialogInterface.OnClickListener {
private OnConfirmDialogClickListener mOnConfirmDialogListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOnConfirmDialogListener = (OnConfirmDialogClickListener) activity;
} catch (ClassCastException ex) {
Log.e(getString(R.string.error_tag), "Activty has to implement " + OnConfirmDialogClickListener.class.getSimpleName() + " interface");
}
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setPositiveButton(R.string.button_text_yes, this)
.setNegativeButton(R.string.button_text_no, this);
Bundle bundle = getArguments();
String message = getString(R.string.message_exit);
String title = getString(R.string.title_exit_message);
int iconId = android.R.drawable.ic_dialog_alert;
if (bundle != null) {
String argumentMessage = bundle.getString(FragmentConstants.Arguments.DIALOG_MESSAGE_ARGUMENT);
String argumentTitle = bundle.getString(FragmentConstants.Arguments.DIALOG_TITLE_ARGUMENT);
int argumentIconId = bundle.getInt(FragmentConstants.Arguments.DIALOG_ICON_ID_ARGUMENT);
message = argumentMessage != null ? argumentMessage : message;
title = argumentTitle != null ? argumentTitle : title;
iconId = argumentIconId != 0 ? argumentIconId : iconId;
}
builder.setIcon(iconId);
builder.setMessage(message);
builder.setTitle(title);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
mOnConfirmDialogListener.onConfirmClick();
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
mOnConfirmDialogListener.onCancelClick();
}
}
public interface OnConfirmDialogClickListener {
void onConfirmClick();
void onCancelClick();
}
}
并且在activity
public class MainActivity extends BaseSingleFragmentActivity implements ExitConfirmDialogFactory.OnExitDialogClickListener {
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
Bundle arguments = new Bundle();
if(mExitDialog==null) {
arguments.putInt(FragmentConstants.Arguments.DIALOG_ICON_ID_ARGUMENT, android.R.drawable.ic_dialog_alert);
arguments.putString(FragmentConstants.Arguments.DIALOG_MESSAGE_ARGUMENT, getString(R.string.message_exit));
arguments.putString(FragmentConstants.Arguments.DIALOG_TITLE_ARGUMENT, getString(R.string.title_exit_message));
DialogFragment exitDialog = new ConfirmationDialog();
exitDialog.setArguments(arguments);
mExitDialog = exitDialog;
}
mExitDialog.show(getSupportFragmentManager(),FragmentConstants.Tags.EXIT_DIALOG_TAG);
} else {
super.onBackPressed();
}
}
@Override
public void onConfirmClick() {
super.onBackPressed();
}
@Override
public void onCancelClick() {
}