Is there a way to make the snackbar push the view upwards when it is shown?
Currently, when the snackbar is shown, it overlays the view below so it looks like half the button is cut off but I want it to almost "adjustPan" similar to the way that the softkeyboard works when it is shown on the screen.
Does anyone know of any tricks to achieve this?
make(parentlayout, "This is main activity", Snackbar. LENGTH_LONG) . setAction("CLOSE", new View. OnClickListener() { @Override public void onClick(View view) { } }) .
Import the snackBarService and inject it inside the constructor of the component, in which you want to use the Snackbar. This will create an instance of the service say snackBService. Now call the openSnackBar function wherever it is required, with the help of snackBService.
Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.
Put your view inside a android.support.design.CoordinatorLayout
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
<View
android:id="@+id/my_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_behavior="com.example.FloatingActionButtonBehavior"/>
</android.support.design.widget.CoordinatorLayout>
The important part here is app:layout_behavior attribute. Here is implementing class:
public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
public FloatingActionButtonBehavior(Context context, AttributeSet attrs) {
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
return dependency instanceof SnackbarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
child.setTranslationY(translationY);
return true;
}
}
Then when you show the snackbar pass the reference to the CoordinatorLayout:
CoordinatorLayout coordinator = findViewById(R.id.coordinator);
Snackbar.make(coordinator, textResId, Snackbar.LENGTH_LONG)
.setAction(R.string.accept_ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
}
})
.setDuration(Snackbar.LENGTH_INDEFINITE)
.show();
Hope this will help you.
Short Answer: If all you want is to push the View upwards when the Snackbar shows up, just add the following line to your View. No need to define FloatingActionButtonBehavior
anymore.
app:layout_dodgeInsetEdges="bottom"
Long Answer: FloatingActionButtonBehavior
described in the accepted answer certainly gets the job done.
One thing I noticed is that, if I have a CoordinatorLayout
and a real FloatingActionButton
with no FloatingActionButtonBehavior
, then the FAB feels slightly "bouncy" when the Snackbar shows up. But if I use something else, such as a ConstraintLayout
along with FloatingActionButtonBehavior
, then the "bouncy" feeling is just not there; the View above the Snackbar just shows up with enough space at the bottom for the Snackbar, and the Snackbar gradually fills the space. It's rather subtle, and I'm sure most people don't even notice it nor care about it.
This is when the Snackbar starts to show up. Notice that its size is slightly smaller than its full size.
And a fraction of a second later, the Snackbar "expands" to its full size.
This is what contributes to the "bouncy" feeling; FAB's location is based on the Snackbar's current size, not the Snackbar's fully shown size.
To replicate this behavior, just let FloatingActionButtonBehavior
know where to anchor FAB, instead of calculating the Y coordinate yourself. Better yet, refer to "Short Answer".
/*
Replicate real FAB's behavior. Code shamelessly stolen from
com/google/android/material/floatingactionbutton/FloatingActionButton.java
*/
class FloatingActionButtonBehavior(
context: Context,
attrs: AttributeSet
) : CoordinatorLayout.Behavior<View>() {
override fun onAttachedToLayoutParams(params: CoordinatorLayout.LayoutParams) {
super.onAttachedToLayoutParams(params)
if (params.dodgeInsetEdges == Gravity.NO_GRAVITY) {
params.dodgeInsetEdges = Gravity.BOTTOM
}
}
}
He is SourceRebeles solution using generics in Kotlin.
typealias T = View
class FloatingActionButtonBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<T>() {
override fun layoutDependsOn(parent: CoordinatorLayout, child: T, dependency: View): Boolean {
return dependency is SnackbarLayout
}
override fun onDependentViewChanged(parent: CoordinatorLayout, child: T, dependency: View): Boolean {
val translationY = Math.min(0.0f, (dependency.translationY - dependency.height).toFloat())
child.translationY = translationY
return true
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With