23

我正在更新我当前的应用程序以使用snackbars,在谷歌规范中他们展示了使用它们的各种方式http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs

示例 A:

带边距的 Snackbar

示例 B:

固定到布局的 Snackbar

这是我的自动取款机代码:

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

我在示例 B 中得到结果,

如何添加边距?

4

18 回答 18

27

除了 Saeid 的回答之外,您还可以获得默认的 SnackBar 布局参数并根据需要进行修改:

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();
}
于 2016-01-17T22:43:49.997 回答
18

以上解决方案都不适合我。

但是,我有一个技巧,我们可以在翻译的帮助下使用。

Snackbar snackbar = Snackbar.make(mActivity.getWindow().getDecorView().getRootView(), message, Snackbar.LENGTH_SHORT);
View snackBarView = snackbar.getView();
snackBarView.setTranslationY(-(convertDpToPixel(48, mActivity)));
snackbar.show();

你可以在这里找到 convertDpToPixel 方法

于 2020-02-08T11:58:59.637 回答
11

借助 Material Components 库,您可以snackbarStyle在应用主题中使用该属性:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
    <item name="snackbarStyle">@style/MySnackbar</item>
</style>

和:

<style name="MySnackbar" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:layout_margin">32dp</item>
</style>

在此处输入图像描述

于 2020-07-12T17:59:41.320 回答
8

我只是添加我的解决方案,因为@BamsMamx 解决方案不起作用我需要添加 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();
}
于 2019-06-12T17:30:24.943 回答
7

添加 CoordinatorLayout 或 Frame Layout 然后设置边距对我不起作用

要解决此问题,请使用可绘制背景,其中使用项目设置边距和形状以设置所需的填充

container_snackbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--    Set Margin Here -->
    <item
        android:left="20dp"
        android:right="20dp"
        android:bottom="10dp"
        android:top="10dp">

        <!-- Insert your shape here: -->
        <shape android:shape="rectangle"  >
            <solid android:color="#FE4C4C" />

            <!-- Padding for inner text-->
            <padding android:left="25dp" android:right="10dp" android:bottom="10dp" android:top="10dp" />
            <corners android:radius="5dp" />

        </shape>
    </item>
</layer-list>

然后从 Activity 中设置 Drawable

MainActivity.java

Snackbar snack = Snackbar
                 .make(activity,"Hello World ",Snackbar.LENGTH_INDEFINITE);
        snack.getView()
        .setBackground(ContextCompat.getDrawable(getApplicationContext(),R.drawable.contianer_snackbar));
        snack.show();

结果

于 2020-09-07T05:27:16.397 回答
3

控制 Snackbar 显示的关键是使用android.support.design.widget.CoordinatorLayout布局。没有它,您的 Snackbar 将始终显示在小型设备的底部和大型设备的左下方。注意:您可以将CoordinatorLayout用作布局的根ViewGroup或布局树结构中的任何位置。

添加后,确保将CoordinatorLayout(或子)作为 Snackbar.make() 命令的第一个参数传递。

通过向您添加填充或边距,您CoordinatorLayout可以控制位置并从屏幕底部移动 Snackbar。

材料设计指南指定了 Snackbar 的最小和最大宽度。在小型设备上,您会看到它填满了屏幕的宽度,而在平板电脑上,您会看到 Snackbar 达到最大宽度,而不是填满屏幕的宽度。

于 2015-07-24T00:46:44.423 回答
3

尝试这个:

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();
于 2015-11-28T08:18:51.430 回答
3

只需将其添加到您的主题中:

<item name="snackbarStyle">@style/SnackbarMessageStyle</item>

并添加样式:

<style name="SnackbarMessageStyle" parent="@style/Widget.MaterialComponents.Snackbar">
    <item name="android:layout_margin">@dimen/snackbarMessageMargin</item>
</style>
于 2020-02-28T12:49:47.617 回答
2

就个人而言,没有提出任何建议的方法(Android 9)
我以以下方式决定。
我在布局中添加了一个不可见的对象(anchor_view)并制作了:

snackbar.anchorView = anchor_view
于 2020-05-20T14:50:48.783 回答
2

大多数以编程方式应用的方法对我来说都不起作用,因为在这个过程Snackbar.SnackbarLayout中以某种方式应用了边距。snackbar.show()所以这就是我接近它的方式并且它起作用了:

    public void showNoInternet(){
    noInternetSnack = Snackbar.make(noInternetSnackParent, "No internet connection", Snackbar.LENGTH_INDEFINITE)
            .setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_SLIDE)
            .setBackgroundTint(PaletteUtils.getSolidColor(PaletteUtils.MATERIAL_RED));

    Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) noInternetSnack.getView();

    TextView snackText = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_text);
    snackText.setTextSize(getResources().getDimension(R.dimen.newsMoreTextSize)/3);
    snackText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
    LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    llp.topMargin = -30;
    llp.bottomMargin = -30;
    snackText.setLayoutParams(llp);

    noInternetSnack.show();

    new Handler().postDelayed(() -> {
        ViewGroup.MarginLayoutParams llp2 = (ViewGroup.MarginLayoutParams) snackbarLayout.getLayoutParams();
        llp2.setMargins(0,8,0,0);
        snackbarLayout.setLayoutParams(llp2);
        }, 300);
}

但是,从活动主题更改为Theme.AppCompat应用Theme.MaterialComponents.DayNight程序主题(仔细检查您是否在清单中的活动主题中使用 Theme.AppCompat)对我来说很有效,但默认情况下它适用于所有小吃店。您可以添加边距,就像我使用此代码删除边距一样。这里的主要内容是延迟snackbarLayout.setLayoutParams(llp2); ,以便将更改应用于布局。这主要是在您为特定用途制作自定义小吃店时使用。

于 2021-07-19T12:11:36.277 回答
1

对于 kotlin 开发人员来说,只是我使用的一些方便的扩展,

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)
}
于 2019-09-24T06:15:57.650 回答
1

它在程序上对我不起作用,所以我是从 styles.xml 中完成的

创建此样式

 <style name="hpr_snackbar_message_style" parent="@style/Widget.MaterialComponents.Snackbar">
        <item name="android:layout_margin">@null</item>
        <!-- Use default Snackbar margins for top/left/right -->
        <item name="android:layout_marginTop">@dimen/mtrl_snackbar_margin</item>
        <item name="android:layout_marginLeft">@dimen/snackbar_margin</item>
        <item name="android:layout_marginRight">@dimen/snackbar_margin</item>
        <!-- Custom bottom margin, this could work for top/left/right too -->
        <item name="android:layout_marginBottom">@dimen/snackbar_margin</item>
    </style>

将其添加到您的父主题

 <style name="parent_theme" parent="Theme.AppCompat.Light">
        <item name="snackbarStyle">@style/hpr_snackbar_message_style</item>
于 2020-10-23T18:20:29.980 回答
1

如果您只想将保证金应用于特定方面,您还应按以下方式实现。例如仅应用底部边距,

 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()
}
于 2020-01-13T12:02:06.027 回答
0

这对我有用的
container是父标签,它是CoordinatorLayout
R.id.bottom_bar是应该显示上面的小吃栏的视图

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

如果您想要额外的边距,那么只需将填充添加到R.id.bottom_bar. 这只有效

于 2019-04-28T08:23:55.710 回答
0

我在 Kotlin 扩展中的解决方案:

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

于 2019-12-28T12:18:01.047 回答
0

其他答案对我不起作用。我已经实现了这个:

SnackBar.class

public  class SnackBar{  
Context context;
Snackbar getSnackbar(View v, String s, View.OnClickListener listener, String action){
    Snackbar sn = Snackbar.make(v, "" + s, Snackbar.LENGTH_LONG);
    sn.setAction("" + action, listener);
    sn.setActionTextColor(Color.CYAN);
    sn.show();
 sn.getView().setBackground(ContextCompat.getDrawable(context,R.drawable.snackbar_shape));
    return sn;
}

在 MainActivity.class 中包括

MainActivity.class:

  // Snackbar.make(v,"Notification for pressing button",Snackbar.LENGTH_LONG).show();
            final SnackBar snackBar=new SnackBar();
           snackBar.context=MainActivity.this;
           snackBar.getSnackbar(v, "Notification for pressing ", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e(TAG,"cancelled");
                    snackBar.onClick=true;
                    
                }
            }, "cancel");

在可绘制目录中

小吃吧形状.xml

<item
    android:left="20dp"
    android:right="20dp"
    android:bottom="10dp"
    android:top="10dp">     
    <shape android:shape="rectangle"  >
        <solid android:color="#F31E1E1E" />    
        <padding android:left="25dp"android:right="25dp" android:bottom="10dp"android:top="10dp" />
        <corners android:radius="7dp" />

    </shape>
</item>
于 2020-10-26T14:11:53.703 回答
0

设置边距:

View viewInSnk = snkbr.getView();
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) snkbr.getView().getLayoutParams();
params.setMargins(5, 5, 5, 5);
snkbr.getView().setLayoutParams(params);

并设置圆角:

viewInSnk.setBackgroundDrawable(getResources().getDrawable(R.drawable.snackbar_shape));

和形状:

<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#313131"/>
    <corners android:radius="4dp"/>
</shape>
于 2020-03-30T12:25:23.300 回答
0

以上解决方案都不适合我。这是我的解决方案,我的想法是用透明的一面创建背景,所以看起来像一个边距。试试这个对我有用:

  1. 为背景创建可绘制对象

     <?xml version="1.0" encoding="utf-8"?>
     <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
         <item>
             <shape android:shape="rectangle">
                 <solid android:color="@color/transparent" />
             </shape>
         </item>
         <item android:top="16dp" android:bottom="16dp" android:left="16dp" android:right="16dp">
             <shape android:shape="rectangle">
                 <solid android:color="#323232" />
                 <corners android:radius="4dp" />
             </shape>
         </item>
     </layer-list>
    
  2. 使用 kotlin 扩展显示 Snackbar 并添加填充

     private fun Snackbar.show(context: Context) {
         this.view.setPadding(Dpx.dpToPx(16), Dpx.dpToPx(16), Dpx.dpToPx(16), Dpx.dpToPx(16))
         this.view.background = context.getDrawable(R.drawable.bg_snackbar)
         show()
     }
    
  3. 调用 Snackbar 制作

     Snackbar.make(view, R.string.my_message, Snackbar.LENGTH_SHORT).show(this)
    

就这样。告诉我这是否有效,谢谢...

于 2020-06-29T12:02:33.747 回答