简体   繁体   中英

Android architecture component navigation: toolbar back button missing, back not working

I'm trying the jetpack navigation and can't show the navigation back button when I move to a new fragment.

NavigationActivity.kt

class NavActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_navigation)

        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)

        val host: NavHostFragment = supportFragmentManager
                .findFragmentById(R.id.navigation_graph) as NavHostFragment? ?: return

        // Set up Navigation
        val navController = host.navController
        setupActionBarWithNavController(navController)
        setupBottomNavMenu(navController)

    }

    private fun setupActionBarWithNavController(navController: NavController) {
        setupActionBarWithNavController(this, navController)
    }

    private fun setupBottomNavMenu(navController: NavController) {
        findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.let { bottomNavView ->
            NavigationUI.setupWithNavController(bottomNavView, navController)
        }
    }

}

activity_navigation.xml

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".views.NavActivity">

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_height="?attr/actionBarSize"
    android:elevation="4dp"
    android:background="?attr/colorPrimary"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    android:layout_width="match_parent">
</androidx.appcompat.widget.Toolbar>
<fragment
    android:id="@+id/navigation_graph"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbar"
    app:navGraph="@navigation/navigation_graph"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:menu="@menu/menu_bottom_nav" />

navigation_graph.xml

<navigation 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"
    app:startDestination="@+id/launcher_home">
    <fragment
        android:id="@+id/launcher_home"
        android:name="com.noisyninja.androidlistpoc.views.main.MainFragment"
        android:label="@string/app_name"
        tools:layout="@layout/fragment_main">

        <action
            android:id="@+id/next_action"
            app:destination="@+id/detailFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />

    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name="com.noisyninja.androidlistpoc.views.detail.DetailFragment"
        android:label="DetailFragment" />
</navigation>

code for navigation:

    /**
     * opens detail activity
     */
    override fun showDetail(view: View, me: Me) {

        var bundle = Bundle()
        bundle.putString("key", "value")
        Navigation.findNavController(view).navigate(R.id.next_action, bundle, null)
    }

没有标题栏

As above when navigation to the second fragment the toolbar goes missing entirely and doesn't show the back button. Hitting the hardware back button also doesn't pop the detail view. The first hit has no effect, the second hit quits the app.

Edit : Your DetailFragment contains the line

DataBindingUtil.setContentView<FragmentDetailBinding>(requireActivity(),
    R.layout.fragment_detail)

which is resetting the content of your Activity to only be your fragment_detail layout, wiping out the NavHostFragment and everything else.

You should be using DataBindingUtil.bind<FragmentDetailBinding>(view)!! instead.

Original answer (you should still do this, but the above answer is actually what solves the problem)

Your ConstraintLayout is missing quite a few constraints (your views should be a vertical chain , where every app:layout_constraintTop_toBottomOf has an alternative app:layout_constraintBottom_toTopOf on the other element, etc.).

Since you have a single set of three vertically aligned items, you don't need a ConstraintLayout - just a LinearLayout is enough:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout
    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:orientation="vertical"
    tools:context=".views.NavActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_height="?attr/actionBarSize"
        android:elevation="4dp"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        android:layout_width="match_parent"/>

    <fragment
        android:id="@+id/navigation_graph"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

Override this method in your Activity with nav_host_fragment

@Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM