Выход из приложения при нажатии кнопки "Назад" в действии с несколькими фрагментами в "Навигационном ящике"

Я работаю над приложением, которому нужен навигационный ящик. Это приложение имеет 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);

            }