【问题标题】:Add margins to Snackbar view向 Snackbar 视图添加边距
【发布时间】:2015-10-09 10:18:25
【问题描述】:

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

示例 A:

示例 B:

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

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

我得到了示例 B 中的结果,

如何添加边距?

【问题讨论】:

    标签: android android-layout android-snackbar snackbar


    【解决方案1】:

    除了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();
    }
    

    【讨论】:

    • 谢谢。只是一个小建议是改用final ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) snackBarView.getLayoutParams();,这将使代码更加通用,因为它适用于大多数布局。
    • 此代码对我不起作用,只需添加黑色边距
    • @FereshtehNaji 你可以看看我的回答。它工作 100%。
    • 这对我也没有影响。
    【解决方案2】:

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

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

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

    你可以找到convertDpToPixel方法here

    【讨论】:

    • 不幸的是,snackbar.getView().setTranslationY() 没有做任何事情,而在我的情况下,snackbar.getView().setTranslationX() 按预期工作。
    【解决方案3】:

    借助 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>
    

    【讨论】:

    • 如何以编程方式将此样式应用到 Snackbar?
    • 默认情况下,它将应用于每个小吃店,因为主题是主 AppTheme,这是菜单中 标记上的默认主题。
    • @UmangKothari 是的,在 ContextThemeWrapper 的帮助下。我们可以创建具有所需小吃店样式的上下文并将其提供给 SnackBar.make() 函数。 SnackBar 会自动配置自己。更多信息在这里:ataulm.com/2019/11/20/using-context-theme-wrapper.html
    【解决方案4】:

    我只是添加我的解决方案,因为 @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();
    }
    

    【讨论】:

    • 谢谢。这是唯一适用于我的情况。我试过其他人。右边距似乎不起作用,但下边距和左边距起作用。
    • @BamsMamx 的解决方案是有效的,但目前你的版本是有效的 :) 我猜他们在 Snackbar 实现中改变了一些东西。
    【解决方案5】:

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

    要解决这个问题,请使用 Drawable Background,其中使用 item 设置 Margin 和 shape 设置所需的 Padding

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

    Result

    【讨论】:

      【解决方案6】:

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

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

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

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

      【讨论】:

        【解决方案7】:

        试试这个:

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

        【讨论】:

          【解决方案8】:

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

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

          并添加样式:

          <style name="SnackbarMessageStyle" parent="@style/Widget.MaterialComponents.Snackbar">
              <item name="android:layout_margin">@dimen/snackbarMessageMargin</item>
          </style>
          

          【讨论】:

          • 这个答案看起来更干净,但它不起作用。你必须在小吃栏中放一些东西才能加载吗?
          • 它不起作用。在注意到这个答案之前我已经尝试过了。
          【解决方案9】:

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

          snackbar.anchorView = anchor_view
          

          【讨论】:

            【解决方案10】:

            大多数以编程方式应用的方法都不适合我,因为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); ,以便将更改应用于布局。这主要是在您为特定用途制作自定义小吃店时使用。

            【讨论】:

              【解决方案11】:

              对于 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)
              }
              

              【讨论】:

                【解决方案12】:

                如果您只想对特定的边应用边距,您还应按以下方式实现。 例如仅应用底部边距,

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

                【讨论】:

                  【解决方案13】:

                  它不适合我的程序,所以我从 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>
                  

                  【讨论】:

                    【解决方案14】:

                    这对我有用
                    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。这只有效

                    【讨论】:

                      【解决方案15】:

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

                      【讨论】:

                        【解决方案16】:

                        设置边距:

                        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>
                        

                        【讨论】:

                          【解决方案17】:

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

                          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 make

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

                          仅此而已。告诉我这是否有效,谢谢...

                          【讨论】:

                            【解决方案18】:

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

                            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");
                            

                            在可绘制目录中

                            snackbar_shape.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>
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2019-08-13
                              • 1970-01-01
                              • 2022-01-20
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多