Выход из приложения при нажатии кнопки "Назад" в действии с несколькими фрагментами в "Навигационном ящике"
Я работаю над приложением, которому нужен навигационный ящик. Это приложение имеет 1 MainActivity и около 10 фрагментов. Когда я нажимаю значок "Ящик навигации" в MainActivity, он отображает 10 фрагментов, чтобы я мог выбрать каждый из них.
Я выбираю фрагмент A, затем B, затем C... в F, например. Когда я нахожусь в фрагменте F и нажимаю кнопку "Назад", он вернет меня к фрагменту E, а затем Назад снова, и мне потребуется фрагмент D...
Моя проблема в том, что когда я вернусь к фрагменту A (из фрагмента B, конечно), и еще раз нажмите кнопку "Назад", я возьму на пустой белый экран (я думаю, что это основной макет мероприятия). И еще раз нажмите "Назад", приложение выйдет.
Что я хочу, когда я вернусь к фрагменту A (последний фрагмент) и нажмите "Назад", приложение выйдет немедленно, а не пустой белый экран больше
Я искал SO и нашел один похожий вопрос, но ответа еще нет, поэтому я должен задать другой вопрос
Как я могу это сделать?
Большое спасибо
Ответы
Ответ 1
Я думаю, что я тот, у кого есть другой вопрос без ответа, поэтому я хочу показать вам свое обходное решение:
Я проверяю, есть ли в моем FrameLayout один ребенок. Если есть, я вернусь один фрагмент. И еще раз проверьте. Поскольку я точно знаю белый экран, мне нужно проверить его после того, как осталось 0 детей. Если существует еще один фрагмент, больше ничего не нужно делать, но если childs == 0, вы хотите попросить оставить действие.
В качестве альтернативы вы можете удалить AlertDialog и закрыть приложение, если вы достигнете этого последнего фрагмента.
@Override
public void onBackPressed() {
FrameLayout fl = (FrameLayout) findViewById(R.id.content_frame);
if (fl.getChildCount() == 1) {
super.onBackPressed();
if (fl.getChildCount() == 0) {
new AlertDialog.Builder(this)
.setTitle("Close App?")
.setMessage("Do you really want to close this beautiful app?")
.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
})
.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
}).show();
// load your first Fragment here
}
} else if (fl.getChildCount() == 0) {
// load your first Fragment here
} else {
super.onBackPressed();
}
}
Ответ 2
просто выйдите из приложения на втором последнем экране
public void onBackPressed() {
if (manager.getBackStackEntryCount() > 1 ) {
// If there are back-stack entries, leave the FragmentActivity
// implementation take care of them.
manager.popBackStack();
} else {
// Otherwise, ask user if he wants to leave :)
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
MainActivity.super.onBackPressed();
}
}).create().show();
}
}
Ответ 3
Удалить addToBackStack() из фрагмента A.
Надеюсь, что это поможет.
Ответ 4
Я только что исправил свою аналогичную проблему. Я адаптировал решение Али Ажара. Поскольку у меня есть активность заставки, я не хотел прекращать приложение, в противном случае, когда я попытаюсь возобновить приложение (нажав кнопку активных приложений на телефоне и выбрав приложение), приложение застряло бы в заставке не переходя к моей основной деятельности. Поэтому вместо
MainActivity.super.onBackPressed();
Я использовал это:
moveTaskToBack(true);
чтобы отобразить начальный экран. Я не нуждался ни в каком подтверждении вывода пользователем, поэтому я удалил код диалога. Я также хотел скорректировать метод replaceFragment (targetFragment, fragmentNameInBackStack), чтобы избежать добавления фрагмента в backstack, если это первый фрагмент, но оказалось, что нет необходимости делать это, потому что мы делаем popup менеджера из задней части, если больше, чем один фрагмент в backstack, поэтому, если есть только один фрагмент, это прекрасно, мы уходим. Это хорошо, потому что я хотел сохранить мое обратное поведение навигации между различными экранами/фрагментами. Итак, вот код:
@Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 1 ) {
manager.popBackStack();
} else {
// if there is only one entry in the backstack, show the home screen
moveTaskToBack(true);
}
}
Ответ 5
Это Легкий способ, чтобы выйти из приложения, просто вставьте ниже кода
@Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 1) {
// If there are back-stack entries, leave the FragmentActivity
// implementation take care of them.
manager.popBackStack();
} else {
// Otherwise, ask user if he wants to leave :)
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// MainActivity.super.onBackPressed();
finish();
moveTaskToBack(true);
}
}).create().show();
}
Ответ 6
Используйте это.. Простое решение, но отлично работает для меня. Это закроет приложение после того, как вы нажмете последний открытый фрагмент.
@Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
Ответ 7
В методе onBack проверяет отсутствие фрагментов, доступных в диспетчере фрагментов... Если его 1-й из них закрывает приложение, используя метод возврата задачи
Ответ 8
Я думаю, вы можете либо не нажать кнопку "Назад", либо закрыть нажатие кнопки "Назад". Вообще, если вы используете навигационный ящик, это не будет проблемой, но вы можете попробовать.
@Override
public void onBackPressed()
{
// Do Here what ever you want do on back press;
}
или вы можете перейти на навигационный ящик
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
Ответ 9
Это то, что сработало для меня.
Если вызвано из MainActivity
supportFinishAfterTransition();
Если вызывается из фрагмента
getActivity().supportFinishAfterTransition();
Ответ 10
Очень поздний ответ. Но я надеюсь, что это поможет кому-нибудь ответить.
С помощью следующего кода я реализую двойной возврат назад (он дает Toast ). Нажмите еще раз, чтобы выйти из, если нажать еще раз, только приложение выйдет.)
getBackStackEntryCount() - укажите текущее количество фрагментов вашего заднего стека.
int backStackEntryCount = getSupportFragmentManager(). getBackStackEntryCount();
если это value == 0 без фрагментов avilable в back stack. поэтому выполните двойной код выхода на задний план.
else разрешает действие обратного действия с помощью super.onBackPressed();
@Override
public void onBackPressed() {
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
//backStackEntryCount==0 -> no fragments more.. so close the activity with warning
if (backStackEntryCount == 0){
if (homePressed) {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click back again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 2000);
} else {
homePressed = true;
}
}
//some fragments are there.. so allow the back press action
else {
super.onBackPressed();
}
}
Глобально объявить эти переменные
boolean homePressed = true, doubleBackToExitPressedOnce = false;
Ответ 11
Этот сработал для меня (Выход двойной щелчок, чтобы выйти из фрагмента)
int backButtonCount = 0;
@SuppressLint({"ResourceAsColor", "ResourceType"})
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
//binding fragment view
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener((v, keyCode, event) -> {
Log.i("Fragment_Home", "keyCode: " + keyCode);
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
Log.e(TAG, "onCreateView: " + "Fragment Hom Key up");
if (backButtonCount >= 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
getActivity().finish();
} else {
Toast.makeText(getContext(), "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
backButtonCount++;
new Handler().postDelayed(() -> {
backButtonCount = 0;
}, 2000);
}