Add margins to Snackbar view

2020-02-07 01:28发布

问题:

I'm updating my current app to use snackbars, in the Google spec they show various ways of using them http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs

Example A:

Example B:

Here's my code atm:

Snackbar snackbar = Snackbar.make(mParentLayout, displayMessage,     
    Snackbar.LENGTH_LONG);
    snackbar.setAction(actionMessage, mClickListener);
    snackbar.show();

I get the result in Example B,

How can i add margins?

回答1:

In addition to Saeid's answer, you can get the default SnackBar layout params and modify them as you want:

public static void displaySnackBarWithBottomMargin(Snackbar snackbar, int sideMargin, int marginBottom) {
    final View snackBarView = snackbar.getView();
    final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) snackBarView.getLayoutParams();

    params.setMargins(params.leftMargin + sideMargin,
                params.topMargin,
                params.rightMargin + sideMargin,
                params.bottomMargin + marginBottom);

    snackBarView.setLayoutParams(params);
    snackbar.show();
}


回答2:

I just add my solution because the @BamsMamx solution's didn't work I need to add getChildAt(0)

  public static void displaySnackBarWithBottomMargin(BaseActivity activity, View main) {
   Snackbar snackbar = Snackbar.make(main, R.string.register_contacts_snackbar, Snackbar.LENGTH_SHORT);
    final FrameLayout snackBarView = (FrameLayout) snackbar.getView();

    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) snackBarView.getChildAt(0).getLayoutParams();
    params.setMargins(params.leftMargin,
                params.topMargin,
                params.rightMargin,
                params.bottomMargin + 100;
    snackBarView.getChildAt(0).setLayoutParams(params);
    snackbar.show();
}


回答3:

The key to controlling the Snackbar display is using a android.support.design.widget.CoordinatorLayout Layout. Without it your Snackbar will always be displayed filled at the bottom on small devices and at the bottom left of large devices. Note: You may use the CoordinatorLayout as the root ViewGroup of your layout or anywhere in your layout tree structure.

After adding it, ensure you are passing the CoordinatorLayout (or child) as the first argument of the Snackbar.make() command.

By adding padding or margins to your CoordinatorLayout you can control the position and move the Snackbar from the bottom of the screen.

The material design guidelines specify a minimum and maximum width of the Snackbar. On small devices you will see it fill the width of the screen, while on tablets you will see the Snackbar hit the maximum width and not fill the width of the screen.



回答4:

Try this:

Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "message", Snackbar.LENGTH_LONG);

View snackBarView = snackbar.getView();
            LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT,      
LayoutParams.WRAP_CONTENT);

params.setMargins(left, top, right, bottom);

snackBarView.setLayoutParams(params);

snackbar.show();


回答5:

For kotlin developers, just some handy extension that I use,

inline fun View.snack(message:String, left:Int = 10, top:Int = 10, right:Int = 10, bottom:Int = 10, duration:Int = Snackbar.LENGTH_SHORT){
 Snackbar.make(this, message, duration).apply {

     val params = CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.MATCH_PARENT, CoordinatorLayout.LayoutParams.WRAP_CONTENT )
     params.setMargins(left, top, right, bottom)
     params.gravity = Gravity.BOTTOM
     params.anchorGravity = Gravity.BOTTOM

     view.layoutParams = params
     show()
 }
}


inline fun View.longSnack(message:String){
   snack(message, duration = Snackbar.LENGTH_LONG)
}


回答6:

This works for me
container is parent tag which is CoordinatorLayout
R.id.bottom_bar is a view on which above snackbar should be shown

    Snackbar.make(container, getString(R.string.copied), Snackbar.LENGTH_LONG).apply {
        val params = view.layoutParams as CoordinatorLayout.LayoutParams
        params.anchorId = R.id.bottom_bar
        params.anchorGravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
        params.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
        view.layoutParams = params
        show()
    }

if yout want additional margin then simply add padding to R.id.bottom_bar. This only works



回答7:

My solution in Kotlin extension:

    fun showSnackBarWithConfirmation(text: String, view: View, action: () -> Unit)  =
        Snackbar.make(view, text, Snackbar.LENGTH_LONG).apply {
            this.view.findViewById(R.id.snackbar_text)
                .setTextColor(view.context.color(R.color.colorBackgroundLight))
            this.view.setBackgroundResource(view.context.color(R.color.colorBackgroundLight))

setAction(view.context.getString(R.string.common_ok)) { action.invoke() } (this.view.layoutParams as ViewGroup.MarginLayoutParams) .apply { setMargins(56,0,56,300) } show() }



回答8:

If you want to apply margin to only specific side(s), you shall also achieve it as below. For example to apply only bottom margin,

 Snackbar.make(yourContainerView, getString(R.string.your_snackbar_message), Snackbar.LENGTH_LONG_orWhateverYouWant).apply {
    val params = view.layoutParams as CoordinatorLayout.LayoutParams
    params.anchorId = R.id.your_anchor_id
    params.anchorGravity = Gravity.TOP_orWhateverYouWant
    params.gravity = Gravity.TOP_orWhateverYouWant
    params.bottomMargin = 20 // in pixels
    view.layoutParams = params
    show()
}