Обратный вызов кнопки возврата на панели инструментов Android никогда не вызывается

Я знаю, что есть много подобных ответов, но я ничего не нашел.

У меня есть действие (MainActivity), которое заботится об отображении разных фрагментов. Кроме того, в действии у меня есть панель навигации, которую я показываю только на одном фрагменте (он скрыт на других).

Проблема в том, что обратный вызов навигации панели инструментов никогда не вызывается. Отображается кнопка «Назад», но нажатие на нее ничего не делает. Также (я не знаю, имеет ли это какое-то значение), но пользователь попадает в этот фрагмент из другого, в котором я делаю те же вещи, что и в этом, за исключением того, что кнопка перехода назад скрыта.

XML для активности таков:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/main_toolbar"
            layout="@layout/toolbar"/>

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>

Включенная панель инструментов:

<?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary"
    app:theme="@style/Base.ThemeOverlay.AppCompat.Dark.ActionBar"/>

Теперь, в действии, я настраиваю панель инструментов и помещаю слушателя на ее кнопку возврата:

setSupportActionBar(mainToolbar);
setTitle(getResources().getString("Some title"));
mainToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onBackPressed();
        }
    });

В этом конкретном фрагменте, где мне нужна кнопка возврата, я делаю это, чтобы показать это:

if (this.context.getSupportActionBar() != null) {
    this.context.getSupportActionBar().setTitle("Fragment title"));          
    this.context.getSupportActionBar().setDisplayHomeAsUpEnabled(true);   
    this.context.getSupportActionBar().setDisplayShowHomeEnabled(true);
}

И, поскольку я не хочу, чтобы панель навигации использовалась / показывалась, во фрагменте я вызываю метод, определенный в действии, которое выполняет этот код:

drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
drawerToggle.setDrawerIndicatorEnabled(false);

person Sven Vidak    schedule 04.08.2016    source источник


Ответы (1)


На определенном фрагменте, где вы хотите отобразить кнопку возврата, просто добавьте этот фрагмент в стопку

добавьте этого слушателя изменений BackStack в Activity

  @Override
public void onBackStackChanged() {
    if (getSupportFragmentManager().getBackStackEntryCount() != 0) 
        mToolbar.setNavigationIcon(R.drawable.ic_action_back);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
    }
}

чтобы добавить в backStack, вы можете использовать эту строку

если вы передадите true в стек addtoback, он добавит и backstack.

public void changeFragment(Fragment fragment, boolean addtobackstack) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.setCustomAnimations(R.anim.fragment_enter, R.anim.fragment_exit);
    fragmentTransaction.replace(R.id.fragment_container, fragment, MainActivity.TAG);
    if (addtobackstack)
        fragmentTransaction.addToBackStack(null);


    fragmentTransaction.commit();
}
person Atiq Ur Rehman    schedule 04.08.2016
comment
Я уже добавляю этот фрагмент в бэкстэк. Кроме того, почему я должен делать одно и то же дважды? Сначала в onCreate, а затем в onBackStackChanged? И, кроме того, каждый раз, когда бэкстэк меняется - person Sven Vidak; 04.08.2016
comment
я написал дважды. вы можете поместить этот код только в прослушиватель BackStackChange - person Atiq Ur Rehman; 04.08.2016
comment
если у вас есть 2 фрагмента, и вы хотите, чтобы кнопка «Назад» включалась, когда отображается 2-й фрагмент, вы можете проверить, есть ли объект второго фрагмента, а затем добавить его в задний стек - person Atiq Ur Rehman; 04.08.2016