support studio snack importar custom bar agregar android android-snackbar

android - studio - Cómo mover una vista por encima de Snackbar al igual que FloatingButton



snackbar android (7)

Tengo un diseño lineal que quiero subir cuando aparece un Snackbar.

Vi muchos ejemplos de cómo hacer esto con FloatingButton, pero ¿qué pasa con una vista regular?


Además de la respuesta de Travis Castillo: para permitir que se activen SnackBars consecutivos, en onDependentViewChanged() , debe cancelar cualquier animación en curso iniciada por onDependentViewRemoved() :

@Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight()); ViewCompat.animate(child).cancel(); //cancel potential animation started in onDependentViewRemoved() ViewCompat.setTranslationY(child, translationY); return true; }

Sin cancelar, el LinearLayout saltará hacia abajo debajo de la 2da SnackBar cuando una SnackBar sea reemplazada por otra SnackBar.


Basado en la respuesta de @Travis Castillo. Problemas resueltos como:

Moving entire layout up and cause the objects on top of view disappear. Doesnt push the layout up when showing SnackBars immediately after eachother.

Así que aquí está el código fijo para MoveUpwardBehavior Class:

import android.content.Context; import android.support.annotation.Keep; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; @Keep public class MoveUpwardBehavior extends CoordinatorLayout.Behavior<View> { public MoveUpwardBehavior() { super(); } public MoveUpwardBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight()); //Dismiss last SnackBar immediately to prevent from conflict when showing SnackBars immediately after eachother ViewCompat.animate(child).cancel(); //Move entire child layout up that causes objects on top disappear ViewCompat.setTranslationY(child, translationY); //Set top padding to child layout to reappear missing objects //If you had set padding to child in xml, then you have to set them here by <child.getPaddingLeft(), ...> child.setPadding(0, -Math.round(translationY), 0, 0); return true; } @Override public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) { //Reset paddings and translationY to its default child.setPadding(0, 0, 0, 0); ViewCompat.animate(child).translationY(0).start(); } }

Estos códigos aumentan lo que el usuario ve en la pantalla y además el usuario tiene acceso a todos los objetos en su diseño mientras se muestra SnackBar.

Si desea que SnackBar cubra los objetos en lugar de empujar y además el usuario tiene acceso a todos los objetos, entonces necesita cambiar el método onDependentViewChanged:

@Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight()); //Dismiss last SnackBar immediately to prevent from conflict when showing SnackBars immediately after eachother ViewCompat.animate(child).cancel(); //Padding from bottom instead pushing top and padding from top. //If you had set padding to child in xml, then you have to set them here by <child.getPaddingLeft(), ...> child.setPadding(0, 0, 0, -Math.round(translationY)); return true; }

y el método enDependentViewRemoved:

@Override public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) { //Reset paddings and translationY to its default child.setPadding(0, 0, 0, 0); }

Desafortunadamente, perderá la animación cuando el usuario deslice para eliminar SnackBar. Y tienes que usar la clase ValueAnimator para realizar animaciones para rellenar cambios que hacen que haya algún conflicto aquí y tienes que depurarlos.

https://developer.android.com/reference/android/animation/ValueAnimator.html

Cualquier comentario sobre la animación para deslizar para eliminar SnackBar apreciado.

Si puede omitir esa animación, entonces puede usarla.

De todos modos, recomiendo el primer tipo.



He escrito una biblioteca que puede agregar vistas adicionales para animar con SnackProgressBar. También incluye progressBar y otras cosas. Pruébelo https://github.com/tingyik90/snackprogressbar

Supongamos que tiene las siguientes vistas para animar.

View[] views = {view1, view2, view3};

Crea una instancia de SnackProgressBarManager en tu actividad e incluye la vista para animar.

SnackProgressBarManager snackProgressBarManager = new SnackProgressBarManager(rootView) .setViewsToMove(views)

Cuando se muestra o se descarta un SnackProgressBar, estas vistas se animarán en consecuencia.


Implementé esto y descubrí que cuando el snackbar desaparecía, la vista permanecía arriba con espacios en blanco en el lugar de los snackbars, aparentemente esto se sabe si las animaciones se han deshabilitado en el dispositivo.

Para solucionar esto, cambié el método onDependentViewChanged para almacenar la posición Y inicial de la vista a la que se adjunta este comportamiento. Luego, al retirar la barra de refrigeradores, restablezca la posición de esa vista a la posición Y almacenada

private static float initialPositionY; @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { initialPositionY = child.getY(); float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); child.setTranslationY(translationY); return true; } @Override public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) { super.onDependentViewRemoved(parent, child, dependency); child.setTranslationY(initialPositionY); }


Voy a dar más detalles sobre la respuesta aprobada porque creo que hay una implementación un poco más simple de la que proporciona ese artículo.

No pude encontrar un comportamiento incorporado que maneje un movimiento genérico de vistas, pero esta es una buena opción de propósito general (de http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior vinculado en otro comentario):

import android.content.Context; import android.support.annotation.Keep; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; @Keep public class MoveUpwardBehavior extends CoordinatorLayout.Behavior<View> { public MoveUpwardBehavior() { super(); } public MoveUpwardBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight()); ViewCompat.setTranslationY(child, translationY); return true; } //you need this when you swipe the snackbar(thanx to ubuntudroid''s comment) @Override public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) { ViewCompat.animate(child).translationY(0).start(); } }

luego, en su archivo de diseño, agregue un layout_behavior como se muestra a continuación:

<LinearLayout android:id="@+id/main_content" android:orientation="vertical" app:layout_behavior="com.example.MoveUpwardBehavior"/>

donde layout_behavior es la ruta completa a su comportamiento personalizado. No es necesario subclase LinearLayout a menos que tenga una necesidad específica de tener un comportamiento predeterminado, lo que parece poco común.


NINGUNA necesidad de diseño de Coordinador usando una vista regular, alinee la barra de refrigerios con la parte inferior de la vista, y coloque el botón en la parte superior, haciendo clic en el botón de lo que sea su lógica, muestre la barra de refrigerios o el diseño lineal.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> /*snackbar code <LinearLayout android:id="@+id/linear_snack bar" android:layout_width="match_parent" android:layout_height="@dimen/margin_45" android:layout_alignParentBottom="true" android:layout_marginTop="@dimen/margin_0" android:background="@color/dark_grey"> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/orange" android:gravity="center" android:textColor="@color/white" android:textSize="@dimen/text_size_h7" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="@dimen/text_size_h7" /> </LinearLayout> <View android:layout_above="@+id/linear_snack bar" </RelativeLayout>