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