如何在对话框覆盖的底部添加 SnackBar

Posted

技术标签:

【中文标题】如何在对话框覆盖的底部添加 SnackBar【英文标题】:How to add a SnackBar on the bottom of a dialog's overlay 【发布时间】:2016-11-14 08:38:53 【问题描述】:

我有一个 android 应用程序,它有许多不同的弹出窗口。我想在屏幕底部的对话框覆盖层上添加一个SnackBar

我尝试了以下代码

if (fragment!= null) 
    Snackbar snackbar = Snackbar.make(fragment.getDialog().getWindow().findViewById(android.R.id.content),
            message, Snackbar.LENGTH_LONG);
    View view = snackbar.getView();
    FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
    params.gravity = Gravity.BOTTOM;
    view.setLayoutParams(params);
    snackbar.show();

SnackBar 出现在居中Dialog 的底部而不是屏幕底部。如果我在当前的Activity 上添加Snackbar,那么它会出现在对话框的覆盖层下。

【问题讨论】:

使用具有 match_parent 高度的自定义布局的自定义对话框,并尝试将该布局的背景设置为透明以与 android 的默认对话框具有相同的感觉。 上图中的对话框已经将宽度和高度的值设置为match_parent 我已经编辑了我的答案,你能检查一下 【参考方案1】:

试试这个解决方案: 使用的材料对话框: custom_dialog_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >
<TextView
    android:id="@+id/text"
    android:layout_
    android:layout_
    android:textColor="@android:color/black"
    android:text="Sample Test for Custom Dialog"
    android:textSize="20sp"
    android:layout_toRightOf="@+id/image"
    android:layout_alignBottom="@+id/image" />/>

<Button
    android:id="@+id/dialogButtonOK"
    android:layout_
    android:layout_
    android:text=" Ok "
    android:layout_below="@+id/text"
    android:layout_centerHorizontal="true" />
    <android.support.design.widget.CoordinatorLayout
    android:layout_
    android:id="@+id/coordinatorLayout"
    android:layout_>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

片段.java

    final MaterialDialog dialog = new MaterialDialog.Builder(context)
                .customView(R.layout.custom_dialog_layout, false)
                .positiveText(R.string.btn_OK)
                .canceledOnTouchOutside(false)

                .negativeText(android.R.string.cancel)
                .onPositive(new MaterialDialog.SingleButtonCallback() 
                                @Override
                                public void onClick(@NonNull final MaterialDialog dialog, @NonNull DialogAction which) 
Snackbar.make(mCoordinatorLayout, "Please Enter All fields!", Snackbar.LENGTH_LONG).show();
                                                    dialog.show();
)

                .build()
 positiveAction = dialog.getActionButton(DialogAction.POSITIVE);
  mCoordinatorLayout = (CoordinatorLayout) dialog.getCustomView().getRootView().findViewById(R.id.coordinatorLayout);
 dialog.show();

【讨论】:

【参考方案2】:

最后,我想我已经做到了你所期望的。即使我对同一个问题添加了几个答案,我也将此答案添加为单独的答案,以便您更清楚。

它的 UI 很脏,我准备得很仓促。你能看到屏幕底部的StackBar。当您单击AlertDialogOK 按钮时,它会显示

这就是我的做法。

以下代码属于custom_dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >

<ImageView
    android:id="@+id/image"
    android:layout_
    android:layout_
    android:src="@mipmap/ic_launcher"/>

<TextView
    android:id="@+id/text"
    android:layout_
    android:layout_
    android:textColor="@android:color/black"
    android:text="Sample Test for Custom Dialog"
    android:textSize="20sp"
    android:layout_toRightOf="@+id/image"
    android:layout_alignBottom="@+id/image" />/>

<Button
    android:id="@+id/dialogButtonOK"
    android:layout_
    android:layout_
    android:text=" Ok "
    android:layout_below="@+id/text"
    android:layout_centerHorizontal="true" />

以下代码属于activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:id="@+id/rootView"
tools:context="com.***.answer.androidcustomdialog.MainActivity">

<TextView
    android:layout_
    android:layout_
    android:text="Hello World!" />

以下代码属于MainActivity.java

package com.***.answer.androidcustomdialog;

import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity 

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final View rootView=(View)findViewById(R.id.rootView);

    AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
    // inflate the custom dialog view
    LayoutInflater inflater=getLayoutInflater();
    final View mDialogView = inflater.inflate(R.layout.custom_dialog_layout, null);
    // set the View for the AlertDialog
    mAlertDialogBuilder.setView(mDialogView);

    Button btn = (Button) mDialogView.findViewById(R.id.dialogButtonOK);
    btn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            // Pass the RootView to the SnackBar
            Snackbar
                    .make(rootView, "SnackBar in Dialog", Snackbar.LENGTH_LONG)
                    .show();
        
    );
    AlertDialog alertDialog = mAlertDialogBuilder.create();
    alertDialog.show();


如有任何需要,请随时提出。在这个例子中,我没有使用片段。如果你需要我也可以帮忙。如果您需要,我也可以发送项目。给我你的电子邮件:)

总而言之,我真正做的是,只需将根布局视图传递给SnackBar就这么简单。

还有一件事..

根据Google Material Design Snackbars & Toasts Usage参考

放置

Snackbars 出现在屏幕上大多数元素的上方,它们在 浮动操作按钮的高度。然而,它们在 比对话框、底部工作表和导航抽屉高。

因此,Snackbar 的高度总是低于对话框。

【讨论】:

感谢您的回答。我想要的是将Snackbar 放在Dialog 上,但正如您在帖子中向我展示的那样,Snackbar 的高度总是低于对话框。 我觉得你可以把这个标记为正确答案,不是吗 好吧,没有冒犯,但这是肯定的,也不是。是的,因为我放弃了将Snackbar 放在对话框上,不,因为如果有人想让Snackbar 覆盖在对话框上,此代码 sn-p 将无济于事。 这根本不是所要求的【参考方案3】:

使用下面的主题进行全屏自定义对话框

<style name="DialogTheme" parent="android:Theme.Dialog">

<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>


<!-- No backgrounds, titles or window float -->
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>

在您的对话框中使用它,如下所示:

dialog = new Dialog(this, R.style.DialogTheme);

要使用上述内容,您应该为自定义对话框使用自定义布局。

dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

试试上面的代码让你的对话框背景透明。

【讨论】:

我尝试了您的解决方案,但在这种情况下,对话框将具有与显示相同的高度,我希望 Dialog 具有 wrap_content 的高度。为了解决这个问题,我尝试在我的资源布局中添加一个新的RelativeLayout 并使其透明,但它的背景似乎是白色的。 @roroinpho21 我已经编辑了我的答案,请检查是否有帮助。 感谢您的快速重播。现在它几乎是我想要的。当我点击透明区域时,我想dismiss 对话框在这一刻没有任何反应。我想我应该添加一个onCLick 事件作为解决方法另外,如果可能的话,我想用透明黑色替换透明颜色,就像我帖子的图片中所示。【参考方案4】:

这里使用LayoutInflater.inflate 代替。尝试根据需要映射代码。 Here you can find more info

 AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
// inflate the custom dialog view
final View mDialogView = inflater.inflate(R.layout.dialog_layout, null);
// set the View for the AlertDialog
mAlertDialogBuilder.setView(mDialogView);

Button btn = (Button) mDialogView.findViewById(R.id.dialog_btn);
btn.setOnClickListener(new View.OnClickListener() 
    @Override
    public void onClick(View view) 
        // Pass the mDialogView to the SnackBar
        Snackbar
                .make(mDialogView, "SnackBar in Dialog", Snackbar.LENGTH_LONG)
                .show();
    
);
AlertDialog alertDialog = mAlertDialogBuilder.create();
alertDialog.show();

如果您需要帮助将其映射到您的代码,请随时询问

【讨论】:

在这种情况下,Snackbar 出现在对话框底部而不是屏幕底部。【参考方案5】:

您将 Dialog 视图解析为

fragment.getDialog().getWindow().findViewById(android.R.id.content)

我建议你改为解析片段布局根视图。

【讨论】:

我是否应该将id 添加到我的顶部布局组件,然后使用findViewById(R.id.my_dialog_parent_component_id) 将其传递给SnackBar 我就是这个意思

以上是关于如何在对话框覆盖的底部添加 SnackBar的主要内容,如果未能解决你的问题,请参考以下文章

如何在底部栏上方显示 Snackbar?

你如何实现底部有按钮的snackbar?

在 Flutter 中打开应用程序时如何显示 Snackbar 或底部工作表?

Android - 我的 Snackbar 出现在底部导航栏的前面而不是它的上方,如何解决?

如何从底部到顶部更改 Android Snackbar 的初始对齐方式?

Angular Material Snackbar 位置