Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to customize snackBar's layout?

Is there any method to change the layout of a snackBar to custom View?

Now it comes black and we can change the background color. But I don't know the right way to inflate a new layout and making it as snackBars background?

Thanks...

like image 424
noobEinstien Avatar asked Sep 08 '15 09:09

noobEinstien


People also ask

What layout is used for snack bar undo?

Creating A Snackbar With An Action Button In Android Studio: make(coordinatorLayout, "Message is deleted", snackbar. LENGTH_LONG) . setAction("UNDO", new View.

How do you customize snackbar in flutter?

We can create flutter snackbar in our application by calling its constructor and there is only one required property to create a snackbar which is content. Usually, we will use a Text widget for content since we need to show some message to the user. We can use other widgets instead if we want.

How do I add actions to snackbar?

If you add an action to a Snackbar , the Snackbar puts a button next to the message text. The user can trigger your action by pressing the button. For example, an email app might put an undo button on its "email archived" message; if the user clicks the undo button, the app takes the email back out of the archive.


2 Answers

The Snackbar does not allow you to set a custom layout. However, as Primoz990 suggested you can get the Snackbar's View. The getView function returns the Snackbar.SnackbarLayout, which is a horizontal LinearLayout object whose children are a TextView and a Button. To add your own View to the Snackbar, you just need to hide the TextView, and add your View to the Snackbar.SnackbarLayout.

// Create the Snackbar Snackbar snackbar = Snackbar.make(containerLayout, "", Snackbar.LENGTH_LONG); // Get the Snackbar's layout view Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView(); // Hide the text TextView textView = (TextView) layout.findViewById(android.support.design.R.id.snackbar_text); textView.setVisibility(View.INVISIBLE);  // Inflate our custom view View snackView = mInflater.inflate(R.layout.my_snackbar, null); // Configure the view ImageView imageView = (ImageView) snackView.findViewById(R.id.image); imageView.setImageBitmap(image); TextView textViewTop = (TextView) snackView.findViewById(R.id.text); textViewTop.setText(text); textViewTop.setTextColor(Color.WHITE);  //If the view is not covering the whole snackbar layout, add this line layout.setPadding(0,0,0,0);  // Add the view to the Snackbar's layout layout.addView(snackView, 0); // Show the Snackbar snackbar.show(); 
like image 199
Mike Avatar answered Sep 21 '22 03:09

Mike


It is possible starting from 25.1.0 revision of Android Support Library

I. Declare custom layout in your values/layout folder.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"           android:orientation="horizontal"           android:layout_width="match_parent"           android:layout_height="wrap_content">  <Button     android:id="@+id/snackbar_action"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_marginLeft="@dimen/design_snackbar_extra_spacing_horizontal"                   android:layout_marginStart="@dimen/design_snackbar_extra_spacing_horizontal"     android:layout_gravity="center_vertical|right|end"     android:paddingTop="@dimen/design_snackbar_padding_vertical"     android:paddingBottom="@dimen/design_snackbar_padding_vertical"     android:paddingLeft="@dimen/design_snackbar_padding_horizontal"     android:paddingRight="@dimen/design_snackbar_padding_horizontal"     android:visibility="gone"     android:textColor="?attr/colorAccent"     style="?attr/borderlessButtonStyle"/>  <TextView     android:gravity="center_vertical|right"     android:id="@+id/snackbar_text"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_weight="1"     android:paddingTop="@dimen/design_snackbar_padding_vertical"     android:paddingBottom="@dimen/design_snackbar_padding_vertical"     android:paddingLeft="@dimen/design_snackbar_padding_horizontal"     android:paddingRight="@dimen/design_snackbar_padding_horizontal"     android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"     android:maxLines="@integer/design_snackbar_text_max_lines"     android:layout_gravity="center_vertical|left|start"     android:ellipsize="end"/>  </LinearLayout> 

Hints:

  • Use @dimen/design_snackbar values to match material design guidelines.
  • Use ?attr/colorAccent to apply your Application Theme changes to Snackbar.

II. Extend BaseTransientBottomBar class.

public class final CustomSnackbar extends BaseTransientBottomBar<CustomSnackbar> {  /**  * Constructor for the transient bottom bar.  *  * @param parent The parent for this transient bottom bar.  * @param content The content view for this transient bottom bar.  * @param contentViewCallback The content view callback for this transient bottom bar.  */ private CustomSnackbar(ViewGroup parent, View content,                 ContentViewCallback contentViewCallback) {     super(parent, content, contentViewCallback); } } 

III. Add BaseTransientBottomBar.ContentViewCallback

public class final CustomSnackbar ...{  ...  private static class ContentViewCallback implements                            BaseTransientBottomBar.ContentViewCallback {    // view inflated from custom layout   private View content;    public ContentViewCallback(View content) {       this.content = content;   }    @Override   public void animateContentIn(int delay, int duration) {       // add custom *in animations for your views       // e.g. original snackbar uses alpha animation, from 0 to 1       ViewCompat.setScaleY(content, 0f);       ViewCompat.animate(content)                 .scaleY(1f).setDuration(duration)                 .setStartDelay(delay);   }    @Override   public void animateContentOut(int delay, int duration) {       // add custom *out animations for your views       // e.g. original snackbar uses alpha animation, from 1 to 0       ViewCompat.setScaleY(content, 1f);       ViewCompat.animate(content)                 .scaleY(0f)                 .setDuration(duration)                 .setStartDelay(delay);   } } } 

IV. Add method to create Snackbar with custom layout and methods to fill it.

public class final CustomSnackbar ...{  ...  public static CustomSnackbar make(ViewGroup parent, @Duration int duration) {  // inflate custom layout  LayoutInflater inflater = LayoutInflater.from(parent.getContext());  View content = inflater.inflate(R.layout.snackbar_view, parent, false);   // create snackbar with custom view  ContentViewCallback callback= new ContentViewCallback(content);  CustomSnackbar customSnackbar = new CustomSnackbar(parent, content, callback); // Remove black background padding on left and right customSnackbar.getView().setPadding(0, 0, 0, 0);    // set snackbar duration  customSnackbar.setDuration(duration);  return customSnackbar;  }   // set text in custom layout  public CustomSnackbar setText(CharSequence text) {  TextView textView = (TextView) getView().findViewById(R.id.snackbar_text);  textView.setText(text);  return this;  }   // set action in custom layout  public CustomSnackbar setAction(CharSequence text, final OnClickListener  listener) {  Button actionView = (Button) getView().findViewById(R.id.snackbar_action);  actionView.setText(text);  actionView.setVisibility(View.VISIBLE);  actionView.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View view) {          listener.onClick(view);          // Now dismiss the Snackbar          dismiss();      }  });  return this; } } 

V. Create instance of CustomSnackbar and call show() method.

CustomSnackbar customSnackbar = CustomSnackbar.make(rooView,      CustomSnackbar.LENGTH_INDEFINITE); customSnackbar.setText("No network connection!"); customSnackbar.setAction("Retry", new View.OnClickListener() {     @Override     public void onClick(View v) {         // handle click here     } }); customSnackbar.show(); 

See more about Snackbar and its customization at materialdoc.com

Full CustomSnackbar.class code :

import android.support.annotation.NonNull; import android.support.design.widget.BaseTransientBottomBar; import android.support.v4.view.ViewCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView;   public class CustomSnackbar extends BaseTransientBottomBar<CustomSnackbar> {      /**      * Constructor for the transient bottom bar.      *      * @param parent The parent for this transient bottom bar.      * @param content The content view for this transient bottom bar.      * @param callback The content view callback for this transient bottom bar.      */     private CustomSnackbar(ViewGroup parent, View content, ContentViewCallback callback) {         super(parent, content, callback);     }      public static CustomSnackbar make(@NonNull ViewGroup parent, @Duration int duration) {         final LayoutInflater inflater = LayoutInflater.from(parent.getContext());         final View content = inflater.inflate(R.layout.snackbar_view, parent, false);         final ContentViewCallback viewCallback = new ContentViewCallback(content);         final CustomSnackbar customSnackbar = new CustomSnackbar(parent, content, viewCallback);          customSnackbar.getView().setPadding(0, 0, 0, 0);         customSnackbar.setDuration(duration);         return customSnackbar;     }      public CustomSnackbar setText(CharSequence text) {         TextView textView = (TextView) getView().findViewById(R.id.snackbar_text);         textView.setText(text);         return this;     }      public CustomSnackbar setAction(CharSequence text, final View.OnClickListener listener) {         Button actionView = (Button) getView().findViewById(R.id.snackbar_action);         actionView.setText(text);         actionView.setVisibility(View.VISIBLE);         actionView.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 listener.onClick(view);                 // Now dismiss the Snackbar                 dismiss();             }         });         return this;     }      private static class ContentViewCallback implements BaseTransientBottomBar.ContentViewCallback {          private View content;          public ContentViewCallback(View content) {             this.content = content;         }          @Override         public void animateContentIn(int delay, int duration) {             ViewCompat.setScaleY(content, 0f);             ViewCompat.animate(content).scaleY(1f).setDuration(duration).setStartDelay(delay);         }          @Override         public void animateContentOut(int delay, int duration) {             ViewCompat.setScaleY(content, 1f);             ViewCompat.animate(content).scaleY(0f).setDuration(duration).setStartDelay(delay);         }     } } 
like image 39
Yakiv Mospan Avatar answered Sep 19 '22 03:09

Yakiv Mospan