web-dev-qa-db-fra.com

Comment afficher Snackbar en haut de l'écran

Comme le dit Android indique

Les barres de collation fournissent une rétroaction légère sur une opération. Ils affichent un bref message en bas de l'écran sur mobile et en bas à gauche sur les gros appareils.

Existe-t-il une alternative permettant d'afficher snackbars en haut de l'écran au lieu du bas?

En ce moment, je fais quelque chose comme ça qui montre un snackbar en bas de l'écran.

Snackbar.make(findViewById(Android.R.id.content), "Hello this is a snackbar!!!", 
Snackbar.LENGTH_LONG).setAction("Undo", mOnClickListener)
.setActionTextColor(Color.RED)
.show();
11
Pankaj

Il est possible de faire apparaître le snack-bar en haut de l'écran en utilisant ceci:

Snackbar snack = Snackbar.make(parentLayout, str, Snackbar.LENGTH_LONG);
View view = snack.getView();
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snack.show();

Du PO:

J'ai dû changer la première ligne:

Snackbar snack = Snackbar.make(findViewById(Android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
160
Adarsh Yadav
CoordinatorLayout coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorLayout);
Snackbar snackbar = Snackbar.make(coordinatorLayout, "Text", Snackbar.LENGTH_LONG);
View view = snackbar.getView();
CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snackbar.show();
40
Vijayan R

Solution combinée parmi celles ci-dessus:

final ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
if (params instanceof CoordinatorLayout.LayoutParams) {
    ((CoordinatorLayout.LayoutParams) params).gravity = Gravity.TOP;
} else {
    ((FrameLayout.LayoutParams) params).gravity = Gravity.TOP;
}
snackbar.getView().setLayoutParams(params);

Souffre toujours de l'animation incorrecte.

11
Martin Vysny

Vous pouvez effectuer les opérations suivantes pour positionner un SnackBar n'importe où dans une mise en page ( Cette méthode ne présente aucun problème d'animation )

1) Selon:

https://developer.Android.com/reference/Android/support/design/widget/Snackbar.html#make (Android.view.View, Java.lang.CharSequence, int)

Marque Snackbar (vue Affichage, texte CharSequence, durée int)

Créez une Snackbar pour afficher un message Snackbar va essayer de trouver une vue parent pour maintenir la vue de Snackbar à partir de la valeur donnée à afficher. Snackbar remontera l'arborescence des vues en essayant de trouver un parent approprié, qui est défini comme un CoordinatorLayout ou la vue du contenu du décor de la fenêtre, selon la première éventualité.

Ainsi, on peut positionner un snackBar n'importe où à l'intérieur d'une disposition simplement en ajoutant une disposition de coordinateur à l'emplacement souhaité et en utilisant cette disposition de coordinateur comme argument de vue dans la méthode Snackbar.make ci-dessus.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
xmlns:app="http://schemas.Android.com/apk/res-auto"
tools:context=".MainActivity"
Android:orientation="vertical"
Android:id="@+id/rl"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:Android="http://schemas.Android.com/apk/res/Android">

<!-- Coordinator Layout used to position the SnackBar -->

<Android.support.design.widget.CoordinatorLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:id="@+id/cl"
    Android:layout_alignParentTop="true"
    Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>

<!-- add your layout here -->

</RelativeLayout>

2) La disposition du coordinateur utilisée pour afficher le SnackBar doit être au-dessus de toutes les autres vues (élévation la plus élevée). Pour ce faire, on peut soit appeler bringToFront() sur la mise en page du coordinateur, soit élever la mise en page du coordinateur (ajouter Android:elevation="10dp" Par exemple)

3) À ce stade, le snackBar apparaîtra à l'emplacement souhaité, mais le snackBar s'affiche avec une animation de bas en haut (comportement par défaut). Afin de réaliser une animation de haut en bas, vous pouvez effectuer les opérations suivantes:

  • Disposition de rotation du coordinateur utilisée dans la méthode Snackbar.make de 180 degrés

4) Après l'étape 3, le snackBar sera affiché avec une animation de haut en bas, mais le message et le texte d'action sont tournés et la gravité est inversée, donc comme étape finale, j'ai fait ce qui suit:

  • A obtenu la vue SnackBar, a trouvé le LinearLayout tenant le TextView responsable de l'affichage du message et le TextView responsable de l'action, et a fait pivoter le LinearLayout parent de 180 degrés

5) Exemple:

public class MainActivity extends AppCompatActivity {

private final String TAG = MainActivity.class.getSimpleName();
private RelativeLayout rl;
private CoordinatorLayout cl;
private CoordinatorLayout cl1;
private CoordinatorLayout cl2;
private CoordinatorLayout cl3;
private CoordinatorLayout cl4;
private Snackbar snackbar_updated;
private Snackbar snackbar_updated1;
private Snackbar snackbar_updated2;
private Snackbar snackbar_updated3;
private Snackbar snackbar_updated4;
private Snackbar snackbar_ordinary;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rl = (RelativeLayout) findViewById(R.id.rl);
    cl = (CoordinatorLayout) findViewById(R.id.cl);
    cl1 = (CoordinatorLayout) findViewById(R.id.cl1);
    cl2 = (CoordinatorLayout) findViewById(R.id.cl2);
    cl3 = (CoordinatorLayout) findViewById(R.id.cl3);
    cl4 = (CoordinatorLayout) findViewById(R.id.cl4);
    cl.bringToFront();
    cl1.bringToFront();
    cl2.bringToFront();
    cl3.bringToFront();
    cl4.bringToFront();

    snackbar_updated = Snackbar.make(cl, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_updated.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });
    /** Snackbar message and action TextViews are placed inside a LinearLayout
     */
    final Snackbar.SnackbarLayout snackBarLayout = (Snackbar.SnackbarLayout) snackbar_updated.getView();
    for (int i = 0; i < snackBarLayout.getChildCount(); i++) {
        View parent = snackBarLayout.getChildAt(i);
        if (parent instanceof LinearLayout) {
            ((LinearLayout) parent).setRotation(180);
            break;
        }
    }

    snackbar_updated1 = Snackbar.make(cl1, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_updated1.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });
    /** Snackbar message and action TextViews are placed inside a LinearLayout
     */
    final Snackbar.SnackbarLayout snackBarLayout1 = (Snackbar.SnackbarLayout) snackbar_updated1.getView();
    for (int i = 0; i < snackBarLayout1.getChildCount(); i++) {
        View parent = snackBarLayout1.getChildAt(i);
        if (parent instanceof LinearLayout) {
            ((LinearLayout) parent).setRotation(180);
            break;
        }
    }

    snackbar_updated2 = Snackbar.make(cl2, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_updated2.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });

    snackbar_updated3 = Snackbar.make(cl3, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_updated3.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });
    /** Snackbar message and action TextViews are placed inside a LinearLayout
     */
    Snackbar.SnackbarLayout snackBarLayout3 = (Snackbar.SnackbarLayout) snackbar_updated3.getView();
    for (int i = 0; i < snackBarLayout3.getChildCount(); i++) {
        View parent = snackBarLayout3.getChildAt(i);
        if (parent instanceof LinearLayout) {
            ((LinearLayout) parent).setRotation(180);
            break;
        }
    }

    snackbar_updated4 = Snackbar.make(cl4, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_updated4.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });

    snackbar_ordinary = Snackbar.make(rl, "Message", Snackbar.LENGTH_INDEFINITE);
    snackbar_ordinary.setAction("Ok", new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });

    rl.post(new Runnable() {
        @Override
        public void run() {
            snackbar_updated.show();
            rl.postDelayed(new Runnable() {
                @Override
                public void run() {
                    snackbar_updated1.show();
                    rl.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            snackbar_updated2.show();
                            rl.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    snackbar_updated3.show();
                                    rl.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            snackbar_updated4.show();
                                            rl.postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    snackbar_ordinary.show();
                                                }
                                            }, 2000);
                                        }
                                    }, 2000);
                                }
                            }, 2000);
                        }
                    }, 2000);
                }
            }, 2000);
        }
    });

}

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
xmlns:app="http://schemas.Android.com/apk/res-auto"
tools:context=".MainActivity"
Android:orientation="vertical"
Android:id="@+id/rl"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:Android="http://schemas.Android.com/apk/res/Android">

<!-- Coordinator Layout used to position the SnackBar -->

<Android.support.design.widget.CoordinatorLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:id="@+id/cl"
    Android:rotation="180"
    Android:layout_alignParentTop="true"
    Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>

<RelativeLayout
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_alignParentTop="true"
    Android:orientation="vertical">

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/appbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:fitsSystemWindows="true">

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="?attr/actionBarSize"
        Android:background="?attr/colorPrimary"
        app:itemIconTint="#333"
        app:itemTextColor="#333"
        app:layout_collapseMode="pin"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

</Android.support.design.widget.AppBarLayout>

    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:layout_below="@id/appbar"
        Android:layout_gravity="bottom">

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="30dp"
            Android:id="@+id/tv_top"
            Android:text="Layout Top"
            Android:gravity="center"
            Android:textSize="15sp"
            Android:textColor="@Android:color/white"
            Android:layout_alignParentTop="true"
            Android:background="@color/colorAccent">
        </TextView>

        <!-- Coordinator Layout used to position the SnackBar -->

        <Android.support.design.widget.CoordinatorLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:id="@+id/cl1"
            Android:rotation="180"
            Android:layout_below="@id/tv_top"
            Android:background="@Android:color/transparent">
        </Android.support.design.widget.CoordinatorLayout>


        <!-- Coordinator Layout used to position the SnackBar -->

        <Android.support.design.widget.CoordinatorLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:id="@+id/cl2"
            Android:paddingBottom="75dp"
            Android:layout_centerInParent="true"
            Android:background="@Android:color/transparent">
        </Android.support.design.widget.CoordinatorLayout>

        <!-- Coordinator Layout used to position the SnackBar -->

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="30dp"
            Android:id="@+id/tv_center"
            Android:text="Center"
            Android:gravity="center"
            Android:textSize="15sp"
            Android:layout_centerInParent="true"
            Android:textColor="@Android:color/white"
            Android:background="@color/colorAccent">
        </TextView>

        <Android.support.design.widget.CoordinatorLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:id="@+id/cl3"
            Android:rotation="180"
            Android:paddingBottom="75dp"
            Android:layout_centerInParent="true"
            Android:background="@Android:color/transparent">
        </Android.support.design.widget.CoordinatorLayout>

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="30dp"
            Android:id="@+id/tv_bottom"
            Android:text="Layout Bottom"
            Android:gravity="center"
            Android:textSize="15sp"
            Android:textColor="@Android:color/white"
            Android:layout_alignParentBottom="true"
            Android:background="@color/colorAccent">
        </TextView>

        <!-- Coordinator Layout used to position the SnackBar -->

        <Android.support.design.widget.CoordinatorLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:id="@+id/cl4"
            Android:layout_above="@id/tv_bottom"
            Android:background="@Android:color/transparent">
        </Android.support.design.widget.CoordinatorLayout>


    </RelativeLayout>

</RelativeLayout>

</RelativeLayout>

6) Résultat:

result

4
Brainnovo

Kotlin-

    val snackBarView = Snackbar.make(view, "SnackBar Message" , Snackbar.LENGTH_LONG)
    val view = snackBarView.view
    val params = view.layoutParams as FrameLayout.LayoutParams
    params.gravity = Gravity.TOP
    view.layoutParams = params
    view.background = ContextCompat.getDrawable(context,R.drawable.custom_drawable) // for custom background
    snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
    snackBarView.show()

sous la ligne résoudra le problème d'animation.

snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE

Solution alternative- snackBarView.anchorView = mention viewId above whom you want to show SnackBar

3
Deepak

2 ans plus tard, voici ma solution ..

La définition de la marge supérieure et inférieure modifie le résultat de l'effet, ... J'ai essayé d'ajouter autant d'options de personnalisation que possible, le remplacement de l'animation est une autre option non écrite ici.

Merci aux réponses de chacun sur plusieurs questions ...

{
    // usage for setSnackBar
    int view = R.id.toolbar;
    String snackMessage = "";
    boolean useAction = false;
    Runnable ifUseActionRunnable = null;
    String actionText = "";
    int leftMargin = 0;
    int topMargin = 0;
    int rightMargin = 0;
    int bottomMargin = 0;
    int backgroundColour = Color.BLACK;
    int textColor = Color.WHITE;
    int duration = Snackbar.LENGTH_LONG;
    setSnackBar(view, snackMessage, useAction, ifUseActionRunnable, actionText, leftMargin, topMargin, rightMargin, bottomMargin, backgroundColour, textColor, duration);

}

Snackbar snb;
public void setSnackBar(int targetView, String snackMessage, boolean useAction, final Runnable ifUseActionRunnable, String actionText , int leftMargin, int topMargin, int rightMargin, int bottomMargin, int backgroundColour, int textColor, int duration)
{
    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);
    if (useAction)
    {
        snb.setAction(actionText, new View.OnClickListener(){
                @Override
                public void onClick(View p1)
                {
                    ifUseActionRunnable.run();

                }
            });
    }
    if (snb.isShown())
    {
        snb.dismiss();
        snb.show();
    }
    else
    {
        snb.show();
    }
}
0
Gadget Guru