3

Following the tips given in this thread I'm setting the bottom margin of a snackbar to ca. 55 dp in order to have it above the FAB.

The code is - as in the other question:

Snackbar snackbar = Snackbar.make(constraintLayoutContent, msg, Snackbar.LENGTH_LONG);
snackbar.setAction(action, v -> snackbar.dismiss());

View snackBarView = snackbar.getView();

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) snackBarView.getLayoutParams();

params.setMargins(params.leftMargin, 
   params.topMargin, 
   params.rightMargin,
   params.bottomMargin + 500);

//params.gravity = Gravity.TOP;

snackBarView.setLayoutParams(params);

snackbar.show();

The problem I'm facing is that if the snackbar is at the bottom of the screen (params.gravity = Gravity.BOTTOM;) the bottom margin is not applied; however if the snackbar is placed at top of the screen (params.gravity = Gravity.TOP; params.topMargin = 500;) the top margin is correctly applied.

Two screenshots of the issue:

top margin correctly applied

bottom margin not applied

Thanks for your help.

EDIT:

The following is my layout xml file. Not sure if this could help, but here we are.

<?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"
    android:id="@+id/coordinatorLayoutContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/constraintLayoutContent">

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
veveve
  • 51
  • 1
  • 7

4 Answers4

3

M.Usman version works for me:

val snackBarView = snackbar.view
snackBarView.translationY = (-getNavigationBarSize(context)).toFloat()
snackbar.show()

@JvmStatic
fun getNavigationBarSize(context: Context): Int {
    val resources = context.resources
    val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
    return if (resourceId > 0) {
        resources.getDimensionPixelSize(resourceId)
    } else getDensity(context).toInt() * 56
}
Denny Weinberg
  • 2,492
  • 1
  • 21
  • 34
  • it is weird behavior. I did not know why margin bottom was not worked. I had to use this method. or i got snackbar under BottomNavigation bar. – NimaAzhd May 11 '21 at 13:52
2

Adding CoordinatorLayout or Frame Layout and then setting margin didn't work for me

To tackle this problem use Drawable Background where use item to set Margin and shape to set desired Padding

container_snackbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--    Set Margin Here -->
    <item
        android:left="20dp"
        android:right="20dp"
        android:bottom="10dp"
        android:top="10dp">

        <!-- Insert your shape here: -->
        <shape android:shape="rectangle"  >
            <solid android:color="#FE4C4C" />

            <!-- Padding for inner text-->
            <padding android:left="25dp" android:right="10dp" android:bottom="10dp" android:top="10dp" />
            <corners android:radius="5dp" />

        </shape>
    </item>
</layer-list>

And then from Activity set that Drawable

MainActivity.java

Snackbar snack = Snackbar
                 .make(activity,"Hello World ",Snackbar.LENGTH_INDEFINITE);
        snack.getView()
        .setBackground(ContextCompat.getDrawable(getApplicationContext(),R.drawable.contianer_snackbar));
        snack.show();

Result

Bhavin Dhodia
  • 139
  • 2
  • 3
0

I am facing a similar issue. Looks like margin bottom only works when you pass CoordinatorLayoutView to Snackbar.make(). I think it has to do with baseTransientBottomBar and most of its behavior such as swipe-to-dismiss will be available after you pass CoordinatorLayoutView. Maybe it's possible to override baseTransientBottomBar for it to apply margin-bottom.

Sher Sanginov
  • 431
  • 5
  • 9
0

Just add this code/call this function after snack.show()

...

snack.show()
snack.setAnimToUnblockBottomNavBar()



... 

private fun Snackbar.setAnimToUnblockBottomNavBar() {
        val animator = ValueAnimator.ofInt(0, 150)
        animator.addUpdateListener { valueAnimator ->
            val valueAnim = valueAnimator.animatedValue
            if (valueAnim is Int) {
                try {
                    val snackBarView: View = this.view
                    val params = snackBarView.layoutParams as FrameLayout.LayoutParams
                    params.setMargins(0, 0, 0, valueAnim)
                    snackBarView.layoutParams = params
                } catch (_: Exception) { /* do nothing */ }
            }
        }
        animator.start()
    }