Move snackbar above the bottom bar
Solution 1
replace your xml ->
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="test.tab_activity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/main_activity_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
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"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/placeSnackBar">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_menu_gallery" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/colorPrimary" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
and The Snackbar code will be
Snackbar.make(findViewById(R.id.placeSnackBar), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Solution 2
With the material components library you can use the setAnchorView
method to make a Snackbar
appear above a specific view.
In your case if you are using a BottomAppBar
and a fab, you should define the fab in the setAanchorView
.
Something like:
FloatingActionButton fab = findViewById(R.id.fab);
Snackbar snackbar = Snackbar.make(view, "Snackbar over BottomAppBar", Snackbar.LENGTH_LONG);
snackbar.setAnchorView(fab);
The result:
With a BottomNavigationView
you can define it as anchorView:
Snackbar snackbar = Snackbar.make(view,"Snackbar over BottomNav",Snackbar.LENGTH_INDEFINITE);
snackbar.setAnchorView(bottomNavigationView);
snackbar.show();
Result:
Solution 3
You can do this programmatically without cluttering your xml with extra CoordinatorLayouts by changing the snackbar's margins.
Java example:
Snackbar snack = Snackbar.make(findViewById(R.id.coordinatorLayout),
"Your message", Snackbar.LENGTH_LONG);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)
snack.getView().getLayoutParams();
params.setMargins(leftMargin, topMargin, rightMargin, bottomBar.height);
snack.getView().setLayoutParams(params);
snack.show();
Kotlin single line:
Snackbar.make(coordinatorLayout, "Your message", Snackbar.LENGTH_LONG).apply {view.layoutParams = (view.layoutParams as CoordinatorLayout.LayoutParams).apply {setMargins(leftMargin, topMargin, rightMargin, bottomBar.height)}}.show()
Solution 4
Assuming your are working with CoordinatorLayout you can modify the Snackbar's layoutparams before calling show(). By setting the anchorId and anchorGravity the snackBar will display above the bottom nav bar:
val layoutParams = snackbar.view.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.anchorId = R.id.navigation //Id for your bottomNavBar or TabLayout
layoutParams.anchorGravity = Gravity.TOP
layoutParams.gravity = Gravity.TOP
snackbar.view.layoutParams = layoutParams
Solution 5
There is great article about how to use it HERE. There you will know how to make snackbar above BottomNavigationBar
Basically the code below presents most common usage of Toolbar
together with BottomNavigationBar
and FrameLayout
as Fragment container
Important! Notice that
- fab button uses anchor to be placed correcty and useCompactPadding to preserve margins
-
BottomNavigationView
uses layout_behaviour to handle scrolling and SnackBar position<android.support.design.widget.AppBarLayout android:id="@+id/myAppBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:descendantFocusability="beforeDescendants" android:focusableInTouchMode="true" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:contentInsetStart="0dp" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/AppTheme.PopupOverlay"/> </android.support.design.widget.AppBarLayout> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.BottomNavigationView android:id="@+id/navigation_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:menu="@menu/bottom_navigation" app:layout_behavior="murt.shoppinglistapp.ui.BottomNavigationBehavior" android:background="?android:attr/windowBackground" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_add_shopping_list" android:layout_width="wrap_content" android:layout_height="wrap_content" app:useCompatPadding="true" app:srcCompat="@drawable/ic_add_24" app:layout_anchor="@id/navigation_bar" app:layout_anchorGravity="top|right" android:layout_gravity="top" />
Implmenetation of Behaviour don't hesitate to use that ! It's easy and friendly ;) (scrolling)
class BottomNavigationBehavior : CoordinatorLayout.Behavior<BottomNavigationView> {
constructor(): super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView,
dependency: View): Boolean {
if (dependency is Snackbar.SnackbarLayout) {
updateSnackbar(child, dependency)
}
return super.layoutDependsOn(parent, child, dependency)
}
private fun updateSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) {
if (snackbarLayout.layoutParams is CoordinatorLayout.LayoutParams) {
val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams
params.anchorId = child.id
params.anchorGravity = Gravity.TOP
params.gravity = Gravity.TOP
snackbarLayout.layoutParams = params
}
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
directTargetChild: View,
target: View,
nestedScrollAxes: Int
): Boolean {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
target: View,
dx: Int,
dy: Int,
consumed: IntArray
) {
if (dy < 0) {
showBottomNavigationView(child)
} else if (dy > 0) {
hideBottomNavigationView(child)
}
}
private fun hideBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(view.height.toFloat())
}
private fun showBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(0f)
}
}
Wladislaw
Software Developer native iOS & Android development react native frontend (HTML, CSS, JS, jQuery) databases
Updated on July 28, 2022Comments
-
Wladislaw over 1 year
I am facing some problems with new bottom bar.
I can't force to move the snackbar above the bottom bar (this is how design guideline told me should be https://www.google.com/design/spec/components/bottom-navigation.html#bottom-navigation-specs).This is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main_activity" android:layout_width="match_parent" android:layout_height="match_parent" /> <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/nav_header_main_activity" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout>
This is my app_bar_main_activity.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.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:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="test.tab_activity"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/appbar_padding_top" android:theme="@style/MyAppTheme.NoActionBar.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/main_activity_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/MyAppTheme.NoActionBar.PopupOverlay"> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_add_white_24dp" /> <android.support.design.widget.TabLayout android:id="@+id/tab_layout" style="@style/AppTabLayout" android:layout_width="match_parent" android:layout_height="56dp" android:background="?attr/colorPrimary" /> </LinearLayout>
The snackbar in main_activity.java looks like this
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(findViewById(R.id.main_content), "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } });
-
Wladislaw about 8 yearsi am facing the problem, that my layout of my fragment is hidden, when i use the method from you. My layout is just somewhere, where i can not see it. Any ideas? It is maybe new question, but it has something to do with your answer.
-
Zahidul Islam about 8 yearsYou mean the Viewpager?
-
Wladislaw about 8 yearsYes, the viewpager is moved (to the top probably?). So i don't see my layout if i use coordinatorlayout there.
-
rahul.ramanujam over 7 yearsdoesn't work for me . I have a tablayout inside the root coordinator layout and trying to show the snackbar above the bottom tablayout.
-
Cheng over 7 yearsI have similar approach, just use bottomMargin of snackbar layout params stackoverflow.com/a/40686399/3304280
-
Carlos Hernández Gil over 7 yearsin my case it works, but the snack slides over the bottom bar, not behind it.
-
Ali Ashraf about 7 yearsThis is indeed a very good answer, just pass nested coordinator-layout view to make() method of snackbar and snack bar will start showing from there.
-
Chad Mx over 6 years@CarlosHernándezGil It slides over because your view at the bottom has a lower elevation / Z-property. Snackbar's have an elevation of 6dp. Increase your view's elevation by setting the elevation property higher than 6dp in XML or a stateListAnimator. See Android Documentation for working with property values animation and visit Material Design Guidelines for elevations.
-
Chad Mx over 6 yearsThis worked for me. Thank you. Should be the accepted answer.
-
RobertoAllende almost 6 yearsI believe this should be the accepted answer, it's a very elegant solution.
-
Ghedeon over 5 yearsThis answer is underrated. This is how you do it!
-
Mark Lapasa over 5 yearsThis answer is incorrect. I've passed a reference to a CoordinatorLayout as the first argument for Snackbar.make() and it does not render above the bottom view footer
-
Joshua King over 5 yearsThis is the recommended solution by Google on Material.io
-
Long Pham almost 4 yearsCool. Work for me.
-
Florian Walther over 3 yearsThis works perfectly for bottom nav + FAB + hide on scroll behavior 👍
-
jajube over 3 yearsI did this and it works, but the Snackbar covers the fab now.
-
Ansshkki over 3 years@jajube To avoid that... You should place the fab in a
Coordinator
layout, and theview
(passed to themake()
function) should be the sameCoordinator
layout where you placed the fab, hope this will help you :) .. tell me the result for that. -
Richard over 3 yearsThis is an elegant solution. I agree that it should be the accepted answer too.
-
Toufic Batache over 3 years@Wladislaw Can you please mark this as the accepted answer? It's the right way to do it. And thanks a lot Gabriele!
-
DIRTY DAVE about 3 yearsThis is the best answer out of all of them
-
kalan nawarathne over 2 yearsBest answer. Was looking for this for a day!
-
Ryan Wong over 2 yearsThe recommended solution mentioned above indeed suggests
.setAnchorView(...)