How to implement a Collapsing Toolbar only in specific fragments

Viewed 1394

I am trying to build an app that displays a standard toolbar across all of its screens, but when the user navigates to screen B, I want to display a Collapsing Toolbar that would display additional information to the user.

The challenge here is that I am following a convention of having one activity containing all common views (toolbar, bottom app bar, FAB etc.) and replacing fragments in the middle of the activity as the user navigates to different screens. I am using navigation component to achieve this. Unfortunately, having shared toolbar has a problem:

  • It either is a standard toolbar across all screens or it's a collapsable toolbar on all screens.

I have tried to hide everything inside the Collapsable toolbar when collapsing is not needed (to prevent the collapsing effect) but this resulted in toolbar not having a title at all. Most likely has something to do with navigation component itself.

I have also thought of having the collapsing toolbar inside a fragment that needs it and simply hide the main toolbar in onResume but the layout itself wouldn't adjust accordingly.

Do you know what other approaches could be taken to solve this issue? The simplest approach would be to simply have a dedicated toolbar for every single fragment but this will be a lot of code duplication and I am trying to avoid this.

Similar questions on StackOverflow haven't helped solving this problem in my case.

The code below doesn't have all of those things I have tried to solve this issue as they didn't work so I removed those changes.

Main Activity

class MainActivity : AppCompatActivity(), OnActivityComponentRequest, NavController.OnDestinationChangedListener {

    private lateinit var floatingActionButton: FloatingActionButton
    private lateinit var appBarLayout: AppBarLayout
    private lateinit var navHostFragment: View

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

        floatingActionButton = fab
        appBarLayout = app_bar_layout
        navHostFragment = include

        setSupportActionBar(toolbar)

        val navigationController = Navigation.findNavController(this, R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(navigationController.graph)

        toolbar.setupWithNavController(navigationController, appBarConfiguration)
        navigationController.addOnDestinationChangedListener(this)
    }

    override fun onDestinationChanged(controller: NavController, destination: NavDestination, arguments: Bundle?) {
        Log.d("MainActivity", "Destination has been changed $destination")
    }

    override fun getFap(): FloatingActionButton {
        return this.floatingActionButton
    }

    override fun hideCollapsableItem() {
        appBarLayout.isGone = !appBarLayout.isGone
        navHostFragment.layout.maxHeight = LinearLayout.LayoutParams.MATCH_PARENT
        navHostFragment.layout.maxWidth = LinearLayout.LayoutParams.MATCH_PARENT
    }
}

activity_main XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        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=".domain.MainActivity"
        android:animateLayoutChanges="true">

    <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/app_bar_layout"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </com.google.android.material.appbar.AppBarLayout>

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

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchorGravity="right|top"
            app:layout_anchor="@+id/bar"
            android:src="@drawable/ic_add_black_24dp"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

contenxt_main XML

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main"
tools:context=".domain.MainActivity">

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

</FrameLayout>
0 Answers
Related