3

I have this layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/non_clickable_account_snackbar_constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <android.support.v7.widget.Toolbar
      android:id="@+id/my_snackbar_toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" />
  <com.google.android.material.button.MaterialButton
      android:id="@+id/my_snackbar_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center"
      android:text="@string/show_account_snackbar"
      android:theme="@style/Theme.GoogleMaterial.DayNight.Bridge"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

I have a customized class:

public final class MySnackbar<AccountT>
    extends BaseTransientBottomBar<MySnackbar<myT>> {

with

super(findTopMostFrameLayout(parent), content, new MySnackbarAnimation(content));

and

when calling "show()", it shows an android snackbar with customized layout.

enter image description here

When I show a my_snackbar it's seen below the bottom navigation bar (z axis).

1) How can I make it on-top of the navigation bar (z-axis)? Or that's the common behavior?

2) How would you make it to be seen top to the bottom navigation bar? (y axis)

Elad Benda
  • 35,076
  • 87
  • 265
  • 471

7 Answers7

4

You likely are having your layout fit to system windows. Although I don't see it in your example, that is exactly what it does. Perhaps it can be set elsewhere as well.

System windows are the parts of the screen where the system is drawing either non-interactive (in the case of the status bar) or interactive (in the case of the navigation bar) content.

Most of the time, your app won’t need to draw under the status bar or the navigation bar, but if you do: you need to make sure interactive elements (like buttons) aren’t hidden underneath them. That’s what the default behavior of the android:fitsSystemWindows="true" attribute gives you: it sets the padding of the View to ensure the contents don’t overlay the system windows.

That means it will also go under the navigation bar at the bottom and the system bar at the top.

There is an easy fix to this. You can apply window insets.

Chris Banes has some nice examples in that blog.

snackbarCustomLayout.setOnApplyWindowInsetsListener { view, insets ->
    view.updatePadding(bottom = insets.systemWindowInsetBottom)
    insets
}

Bear in mind that you might also need to apply left and / or right insets to deal with landscape modes.

Knossos
  • 15,802
  • 10
  • 54
  • 91
0

I think setting up an elevation in your Snackbar should do the job.

If you are using a custom layout for your snackbar, you might consider putting the android:elevation to that. You can do that programmatically as well.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
  • you added the `elevation` to the constraintLayout (?) not to the snackbar which has no xml presence ? – Elad Benda Mar 21 '20 at 20:15
  • I thought this is the custom layout for your snackbar. – Reaz Murshed Mar 21 '20 at 20:27
  • I have removed the code from my answer. However, I think setting up elevation should be working in your case. It would be great if you could post some of your code on how you are showing the snackbar, so that we could take a look. – Reaz Murshed Mar 21 '20 at 20:32
0

I think this would work.

Snackbar  snb = Snackbar.make(findViewById(targetView), snackMessage, duration);
View view = snb.getView();
view.setBackgroundColor(backgroundColour);
snb.setActionTextColor(textColor);
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity =  Gravity.CENTER_HORIZONTAL | Gravity.TOP;
params.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
view.setLayoutParams(params);
0

Easiest way is to set AnchorView to the bottom navigation drawer(if available).

Snackbar snackbar= Snackbar.make(view, text, duration);
snackbar.setAnchorView(bottomBar);

Also please check your theme & style implementations. Your issue can also arise due to improper theme and styling.

Nick
  • 195
  • 1
  • 5
0

Snackbar has a lot of limitations to implement in different scenarios, You can use this library for the same SuperToasts

SuperActivityToast.create(context, new Style(), Style.TYPE_BUTTON).setButtonText("Open").setAnimations(Style.ANIMATIONS_POP).show();
Amit Kumar
  • 438
  • 1
  • 4
  • 15
0

I agree with @Knossos you can also do one thing that you can get the height of the navigation bar and can give margin to your custom snack bar or show the snack bar inside a view which is above the navigation panel

sourabh kaushik
  • 523
  • 4
  • 20
0

ViewGroup.MarginLayoutParams for Snackbar's view has been stop working since material-1.1.0 library version. To define custom margins, you need to define custom Snackbar's style in your styles.xml:

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
//your items
    <item name="snackbarStyle">@style/Snackbar</item>   //custom snackbar style
</style>

<style name="Snackbar" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:layout_margin">@null</item>
    <item name="android:layout_marginTop">0dp</item>
    <item name="android:layout_marginLeft">0dp</item>
    <item name="android:layout_marginRight">0dp</item>
    <item name="android:layout_marginBottom">50dp</item>   //custom bottom margin
</style>
Jane
  • 61
  • 7