将边距添加到Snackbar视图

时间:2015-07-20 10:20:27

标签: android android-layout android-snackbar

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

示例A:

Snackbar with margin

例B:

Snackbar pinned to layout

这是我的代码atm:

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

我得到了例B中的结果,

如何添加保证金?

18 个答案:

答案 0 :(得分:18)

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

答案 1 :(得分:10)

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

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

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

答案 2 :(得分:5)

使用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>

enter image description here

答案 3 :(得分:3)

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

要解决此问题,请使用Drawable Background,其中使用项目设置边距,使用形状设置所需的填充

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>

然后从“活动”设置该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

答案 4 :(得分:2)

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

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

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

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

答案 5 :(得分:2)

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

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

并添加样式:

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

答案 6 :(得分:1)

大多数以编程方式应用的方法对我来说都不起作用,因为 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); 以便将更改应用于布局。这个主要是针对特定用途的定制小吃店的时候用的。

答案 7 :(得分: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()
}

答案 8 :(得分: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)
}

答案 9 :(得分:1)

试试这个:

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

答案 10 :(得分: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() }

答案 11 :(得分: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>

答案 12 :(得分:0)

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

snackbar.anchorView = anchor_view

答案 13 :(得分: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)
    

仅此而已。告诉我是否可行,谢谢...

答案 14 :(得分:0)

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

答案 15 :(得分: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中添加填充。这只有效

答案 16 :(得分:0)

它不是为我编程的,所以我是从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>

答案 17 :(得分:0)

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

SnackBar.class

class LLBFiche {
    public function register()
    {
        add_action('init', [$this, 'customPostType']);
    }


    public function customPostType()
    {
        $args = [
            'label' => 'LLB Fiches',
            'supports' => [
                'title',
                'editor',
                'thumbnail'
            ],
            'menu_icon' => 'dashicons-welcome-learn-more',
            'public' => true
        ];
        register_post_type('llb_fiche', $args);
    } 
}

MainActivity.class包含中的

MainActivity.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;
}

在可绘制目录中

snackbar_shape.xml

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