martinseal1987
martinseal1987

Reputation: 2429

Snap scroll flag only on toolbar in collapsing toolbar

I have a collapsing toolbar with a pinned toolbar, I want the collapsing toolbars free space to be allowed to scroll freely but the pinned toolbar to snap open or closed, my question is can this be achieved with scroll flags or will i need to create a custom layout behaviour or do some disabling and enabling of the flags based on the toolbars offset so to illustrate what i want here are some images,

Id like to allow this example of it being fully expanded

fully expanded

This would be an example of the scrolling freely free space (no snapping)

half scroll

This would be the collapsing toolbar fully scrolled and the pinned toolbar

collapsed

But I never want to allow this

toolbar not snapping

This is the pinned toolbar also being allowed to scroll freely (as its a child of the collapsing toolbar) I want just this toolbar to have a scroll flag of snap but in practice this doesn't work the toolbars flags are ignored

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"
        app:titleEnabled="false"
        app:title=""
        app:titleTextColor="@android:color/transparent"
        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/squareangle"
            app:titleTextColor="@android:color/transparent"
            app:title=""
            android:elevation="@dimen/large_margin_32dp"
            android:layout_gravity="top"
            android:minHeight="?attr/actionBarSize"
            app:elevation="@dimen/large_margin_32dp"
            app:layout_scrollFlags="snap"
            app:layout_collapseMode="pin"/>

Upvotes: 1

Views: 957

Answers (2)

martinseal1987
martinseal1987

Reputation: 2429

Thanks to Thracian i ended up with something like this

private fun handleAppBarSnapFlag() {
    binding.appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        if (abs(verticalOffset) >= appBarLayout.totalScrollRange - getToolbarHeight()) {
            val toolbarParams = binding.collapsingToolbar.layoutParams as AppBarLayout.LayoutParams
            toolbarParams.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED or SCROLL_FLAG_SNAP
        } else {
            val toolbarParams = binding.collapsingToolbar.layoutParams as AppBarLayout.LayoutParams
            toolbarParams.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
        }
    })
}

Upvotes: 1

Thracian
Thracian

Reputation: 66869

You can set scroll flags with

toolbarParams.setScrollFlags(SCROLL_FLAG_SCROLL | SCROLL_FLAG_ENTER_ALWAYS)

or by shifting as you can see here, this is a sample playground to test Toolbar features.

Also you check AppbarLayout offset using

appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->

    //Check if the view is collapsed
    if (abs(verticalOffset) >= appbar.totalScrollRange) {
        collapsingToolbar.title = "Collapsed"
    } else {
        collapsingToolbar.title = ""
    }

     // Change flags based on position of offset

})

I used this to create scrolling behavior over appbar for RecyclerView as can be seen here

Upvotes: 2

Related Questions