Issue
I am trying to implement confirm message to exit from my app. I need this, because someone can accidentally click back button more than one time and this will close the app and in case of low memory it will be killed after that because now it is not in foreground.
I have tried different approaches, but some of them required a lot of checks, others doesn't work at all.
I have tried to use onKeyDown event, onBackPressed ...
The problem because I am working not with only with activities, but also with nested fragments (inside activities).
I need to handle the last on back pressed click before exit, so it means that all fragments of current activity have to be popped up from the stack, than activity has to be popped up also and that if this is not last activity do the same for the preceding activity until this is not last activity and all fragments are popped up in it.
How can I implement this ? I have tried to do this using backstack, but unfortunately haven't succeed.
Please suggest what is the best to handle such type of event. I guess that there is an easy way to do this.
Solution
Thanks everyone for answers and suggestions.
I have reached the desired result by using fragment count in the stack.
As far as my Main Activity will be the first activity and the last before exit, I can override onBackPressed method inside it.
So solution is simple.
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();
}
}
}
So this will work only if your activity is last in Activity Stack , so you have to override it your launcher activity, not in some base activity class or other.
A little bit improved solution to my mind.
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();
}
}
And in 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() {
}
Answered By - CROSP
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.