Comment déplacer une vue ci-dessus Snackbar comme FloatingButton

J'ai eu une disposition linéaire que je veux déplacer vers le haut quand une Snackbar apparaît.

J'ai vu de nombreux exemples comment faire cela avec FloatingButton, mais qu'en est-il d'une vue régulière?

  • Get String from EditText
  • Passer au prochain EditText dans Android
  • Combinaison de ListActivity et ActionBarActivity
  • Sujet en direct en direct
  • Android - OkHttp interceptor - réponse déjà "consommée"
  • La session SSL n'est pas réutilisée dans Android WebView
  • Impossible de trouver la variable d'environnement 'ANDROID_HOME'
  • Convertir le texte de chaîne en bitmap
  • Comment puis-je rendre inactif un look d'état de "désactivé" de Spinner?
  • Comment puis-je activer des Cookies tiers sous Phonegap et Android 3.2?
  • Etiquette verticale (tournée) dans Android
  • Facebook SDK pour Android lançant l'exception ClassNotFound
  • 6 Solutions collect form web for “Comment déplacer une vue ci-dessus Snackbar comme FloatingButton”

    Vous devez ajouter un comportement à votre LinearLayout et l'intégrer dans un CoordinatorLayout. Vous voudrez peut-être lire ceci: http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior

    Je vais élaborer la réponse approuvée parce que je pense qu'il y a une mise en œuvre légèrement plus simple que celle fournie par cet article.

    Je n'ai pas pu trouver un comportement intégré qui gère un déplacement générique de vues, mais celui-ci est une bonne option générale (à partir de http://alisonhuang-blog.logdown.com/posts/290009-design-support -library-coordinator-layout-and-behavior linked dans un autre commentaire):

    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(); } } 

    Ensuite, dans votre fichier de mise en page, ajoutez un layout_behavior comme ci-dessous:

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

    Où le layout_behavior est le chemin d'accès complet à votre comportement personnalisé. Il n'est pas nécessaire de sous-classer LinearLayout, sauf si vous avez un besoin spécifique d'avoir un comportement par défaut, ce qui semble peu commun.

    J'ai implémenté cela et j'ai constaté que lorsque la barre de restauration a disparu, la vue est restée avec des espaces blancs dans la place des snacks, apparemment, on sait si les animations ont été désactivées sur le périphérique.

    Pour corriger cela, j'ai changé la méthode onDependentViewChanged pour stocker la position Y initiale de la vue à laquelle ce comportement est associé. Ensuite, lors du retrait de la restauration du snack, la position de cette vue sur la position Y stockée

     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); } 

    Basé sur la réponse de @Travis Castillo. Résolution de problèmes tels que:

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

    Voici donc un code fixe pour la classe MoveUpwardBehavior:

     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(); } } 

    Ce code augmente ce que l'utilisateur voit à l'écran et, en plus, l'utilisateur a accès à tous les objets de votre mise en page alors que SnackBar s'affiche.

    Si vous voulez que le SnackBar couvre les objets au lieu de pousser et, en plus, les utilisateurs ont accès à tous les objets, alors vous devez modifier la méthode 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; } 

    Et méthode onDependentViewRemoved:

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

    Malheureusement, vous perdrez de l'animation lorsque l'utilisateur glisse pour supprimer SnackBar. Et vous devez utiliser la classe ValueAnimator pour faire de l'animation des changements de rembourrage qui entraînent certains conflits ici et vous devez les déboguer.

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

    Tout commentaire sur l'animation pour glisser pour supprimer SnackBar apprécié.

    Si vous pouvez ignorer cette animation, vous pouvez l'utiliser.

    De toute façon, je recommande le premier type.

    En plus de la réponse de Travis Castillo: Pour autoriser le déclenchement de SnackBars consécutifs, dans onDependentViewChanged() , vous devez annuler toute animation éventuellement commencée par 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; } 

    Sans annuler, le LinearLayout sautera en dessous du 2nd SnackBar lorsqu'un SnackBar est remplacé par un SnackBar.

    NON besoin d'une disposition de coordonnateur en utilisant une vue régulière aligner la barre de snack au bas de la vue, et placez le bouton en haut de lui, sur le bouton de clic de tout ce que votre logique est afficher snackbar ou la disposition linéaire.

     <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> 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.