The above special effect is the effect of Toolbar combined with CoordinatorLayout/AppbarLayout/CollapsingToolbarLayout; Using these views alone has no effect. Generally, they need to cooperate with each other.
brief introduction
- CoordinatorLayout: Coordinator means coordinator after translation. It is mainly used to coordinate how the sub View responds to rolling events. It is generally used in conjunction with NestedScrollView to coordinate the processing of rolling events of the sub View
- AppbarLayout: is an App Bar layout that supports responding to scrolling gestures. It inherits from LinearLayout. The child views are displayed through app:layout_scrollFlags control behavior; Its first child View must be set with [app:layout_scrollFlags = "scroll"], or other child views cannot scroll in linkage
- app:layout_scrollFlags = "scroll": scroll with the gesture until it disappears
- app:layout_scrollFlags = "scroll|snap": with adsorption effect, if the sliding distance exceeds half of the view, it will be automatically hidden or displayed
- app:layout_scrollFlags = "scroll|enterAlways": follow the gesture to scroll until it disappears and is displayed whenever the gesture is pulled down
- app:layout_scrollFlags = "scroll|enteralways|enteralwaysclapsed": follow the gesture to scroll until it disappears and is invisible. At any time, the state of Toolbar folding is displayed when the gesture is pulled down. It needs to be used in combination with [CollapsingToolbarLayout]
- app:layout_scrollFlags = "scroll|exitUntilCollapsed": follow the gesture to scroll until the CollapsingToolbarLayout is folded, that is, the top of the Toolbar is visible all the time. It needs to be used with [CollapsingToolbarLayout]
- CollapsingToolbarLayout: works with toolbars and supports folding / expanding toolbars
- app:layout_collapseMode = "parallax": the Menu on the Toolbar will not be displayed after folding, only the Title will be displayed
- app:layout_collapseMode = "pin": the Menu on the Toolbar is still displayed after folding
- app:contentScrim="?attr/colorPrimary": the Toolbar background color displayed when the Toolbar is collapsed
- Toolbar:
- android:background="?attr/colorPrimary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
- app:layout_scrollFlags="scroll"
- app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
- app:title = "my app"
- Nested ScrollView: nested means nested after translation. It is a ScrollView that supports nested sliding, which means that it will automatically handle sliding conflicts
- app:layout_behavior="@string/appbar_scrolling_view_behavior": when scrolling, coordinate through CoordinatorLayout to link the child views of AppbarLayout
Linkage effect
The following will look at how different linkage effects are achieved from simple to deep
Effect 1:
As the main interface scrolls up, the Toolbar will be hidden slowly; When the main interface scrolls down to the top, the Toolbar is gradually displayed
<?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=".MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_scrollFlags="scroll" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" /> </com.google.android.material.appbar.AppBarLayout> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/mClickButton" android:layout_width="wrap_content" android:layout_height="1000dp" android:text="Hello World!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> </LinearLayout> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout>
Simply understand the above layout: when a scrolling event is generated by touching, because NestedScrollView is configured with [app:layout_behavior="@string/appbar_scrolling_view_behavior"], CoordinatorLayout will coordinate NestedScrollView and pass the scrolling event to AppBarLayout at an appropriate time, AppBarLayout determines how to respond to the scrolling event according to the [app:layout_scrollFlags = "scroll"] attribute of the sub View (Toolbar), [scroll] means that when the scrolling event occurs, the sub View (Toolbar) also follows the scrolling event
Effect 2
On the basis of [effect 1] Toolbar scrolling with gesture, the Toolbar has adsorption effect, that is, when the height of the Toolbar is hidden or more than half of the Toolbar is displayed and scrolling is stopped, it will be automatically displayed / hidden completely
<androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_scrollFlags="scroll|snap" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" />
Key code: [app:layout_scrollFlags = "scroll|snap"], which means to follow the scroll with adsorption effect
Effect 3
On the basis of [Effect 2], no matter [NestedScrollView] scrolls to any position, when the gesture is pulled down, the Toolbar will always be displayed; [Effect 2] the Toolbar will be displayed only when [NestedScrollView] scrolls to the top and continues to drop down
Key code: [app:layout_scrollFlags = "scroll|snap|enterways"], indicating [follow scroll] [with adsorption effect] [drop-down display regardless of scrolling to any position]
Effect 4: used with CollapsingToolbarLayout
[Collapsing] means folding. When used together with the Toolbar, the Toolbar can have the effect of folding / expanding. Note the following points:
- CollapsingToolbarLayout must specify a specific height, not [wrap_content], otherwise [app:title] cannot be displayed
- [app:layout_scrollFlags] attribute should be added to [CollapsingToolbarLayout] instead of [Toolbar]
<com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="150dp" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_scrollFlags="scroll|snap|enterAlways"> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" /> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout>
Effect 5
On the basis of [effect 4], when you pull down at any position, the Toolbar only displays the folded height, and it will not be fully displayed until you scroll to the top and continue to pull down
Key code [app:layout_scrollFlags = "scroll|snap|enteralways|enteralwaysclapsed"]; [enteralwaysclapsed] indicates that it always enters in the folded state, which is meaningful only when it is used with [CollapsingToolbarLayout];
Effect 6
[effect 5] you can see that the folded Toolbar does not display [Menu]. To solve this problem, you need to add another attribute [app:layout_collapseMode = "pin"] to the Toolbar
<androidx.appcompat.widget.Toolbar app:layout_collapseMode="pin" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" />
Effect 7
On the basis of [effect 6], what if the Toolbar in the folded state is always displayed instead of being completely hidden when dragging upward?
- Modify the attribute of [CollapsingToolbarLayout] to [app:layout_scrollFlags = "scroll|exitUntilCollapsed"]
- [exitUntilCollapsed] means to scroll to the Toolbar and fold it up
<com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="150dp" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <androidx.appcompat.widget.Toolbar app:layout_collapseMode="pin" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" /> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout>
Effect 8: add a beautiful background to the Toolbar
Since [CollapsingToolbarLayout] inherits from [FrameLayout], you can add other views in addition to the Toolbar. Add a background to the Toolbar, that is, add an additional [Image View] on the Toolbar
<com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="150dp" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/ic_snow_mountain"/> <androidx.appcompat.widget.Toolbar app:layout_collapseMode="pin" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" /> </com.google.android.material.appbar.CollapsingToolbarLayout>
Effect 9: when folded, the Toolbar displays a solid background
You can see that [effect 8] adding a background color is beautiful, but sometimes we want the toolbar to display a solid color background after folding, and the picture background after expanding
- Just add an attribute [app:contentScrim] on [CollapsingToolbarLayout] to specify the background color of the Toolbar after folding
Full layout file code:
<?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=".MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="150dp" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/ic_snow_mountain" /> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_collapseMode="pin" app:menu="@menu/main_menu" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My app" /> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:id="@+id/mMainContentView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/mClickButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </LinearLayout> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout>