BottomSheetDialog透明背景

Pie*_*rre 23 android

我想显示一个比屏幕宽度宽的底部对话框.

例如,Nexus 9上的Google Play音乐分享选项.

Nexus 9上的Google Play音乐分享选项

你知道如何实现这个目标吗?

现在我刚刚尝试减少工作表内容的宽度,但背景仍然在屏幕宽度并显示白色背景.

一些代码:

的build.gradle

compile 'com.android.support:design:23.3.0'
Run Code Online (Sandbox Code Playgroud)

主要活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    mBottomSheetDialog = new BottomSheetDialog(this);
    mBottomSheetDialog.setContentView(R.layout.sheet_test);
    mBottomSheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
        @Override
        public void onDismiss(DialogInterface dialog) {
            mBottomSheetDialog = null;
        }
    });
    mBottomSheetDialog.show();
}
Run Code Online (Sandbox Code Playgroud)

sheet_test

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            style="@style/TextAppearance.AppCompat.Body1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="Some Text"
            android:textColor="@color/colorPrimary" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#ddd" />

        <TextView
            style="@style/TextAppearance.AppCompat.Body1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="16dp"
            android:text="Some Text" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#ddd" />

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

Gnz*_*zlt 64

这在使用时对我有用BottomSheetDialogFragment:

public class CustomDialogFragment extends BottomSheetDialogFragment {

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme);
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

同时将此添加到您的 styles.xml

<style name="CustomBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheetStyle</item>
</style>

<style name="CustomBottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@android:color/transparent</item>
</style>
Run Code Online (Sandbox Code Playgroud)

  • 对于其他人来说,只是注释,setStyle调用在onCreateView方法中不起作用.像上面的例子一样使用时效果很好.谢谢你的解决方案! (6认同)
  • 这必须被选为答案,就像一个魅力! (6认同)
  • 我尝试了很多解决方案,这是唯一对我有用的解决方案,非常感谢:D (4认同)
  • 这就像一种魅力,对。我建议添加一个更新以使用新的[`Theme.MaterialComponents`](https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android /material/bottomsheet/res/values/themes.xml):在这种情况下,主题为`Theme.MaterialComponents.Light.BottomSheetDialog`。 (3认同)
  • @Mr.Drew Fragment 中的 `onCreate()` 方法在 Activity 的 `onAttachFragment()` 之后但在该 Fragment 的 `onCreateView()` 之前调用。在此方法中,您可以分配不涉及View层次结构的变量(即非图形初始化)。`onCreateView()` 在 `onCreate()` 之后调用,这里我们附加对话框的视图。对话框本身有一个已经在“onCreate()”中创建的框架。因此,该框架只能在“onCreate()”方法中删除。 (2认同)

Jay*_*hit 41

这是设置BottomSheetDialogFragment透明背景的最简单的解决方案

((查看)contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));

public class ShareOneTouchAlertNewBottom extends BottomSheetDialogFragment {
    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sheet, null);
        dialog.setContentView(contentView);

        CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent())
                .getLayoutParams();
        CoordinatorLayout.Behavior behavior = params.getBehavior();
        ((View) contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 考虑使用`Color.TRANSPARENT`而不是`getResources()。getColor(android.R.color.transparent)` (2认同)

小智 33

BottomSheetDialog bottomSheetDialog =new BottomSheetDialog(this,R.style.SheetDialog);
Run Code Online (Sandbox Code Playgroud)

样式xml代码

<style name="SheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
    <!--<item name="android:windowCloseOnTouchOutside">false</item>-->
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:colorBackground">     @android:color/transparent</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:backgroundDimAmount">0.3</item>
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
</style>
Run Code Online (Sandbox Code Playgroud)


Mar*_* RS 15

以下函数覆盖在一个BottomSheetDialogFragment实现中起作用:

class MyTopicBottomSheet : BottomSheetDialogFragment() {


    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

       return super.onCreateDialog(savedInstanceState).apply {
           // window?.setDimAmount(0.2f) // Set dim amount here
           setOnShowListener {
            val bottomSheet = findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
            bottomSheet.setBackgroundResource(android.R.color.transparent)
           }
       }
    }

    // Rest of your class here
}
Run Code Online (Sandbox Code Playgroud)


小智 12

对不起,晚了,如果您成功完成,这就是您要寻找的投票

  @Override    
  public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ((View) getView().getParent()).setBackgroundColor(Color.TRANSPARENT);
}
Run Code Online (Sandbox Code Playgroud)

添加此行是最下面的对话框片段,这可以解决问题


cha*_*uze 11

有几种黑客方法可以做到这一点。我解决这个问题的方法是推荐的方法。让我们了解一下为什么?

在文档中,提到了

莫代尔底片。这是 DialogFragment 的一个版本,它使用 BottomSheetDialog 而不是浮动对话框显示底部工作表。

这意味着应该有一个方法用于BottomSheetDialogFragment将默认值替换DialogBottomSheetDialog.

唯一BottomSheetDialogFragment覆盖的方法是onCreateDialog(). 所以我们将使用这个公共方法来覆盖我们的对话框样式。

推荐方法

BottomSheetDialogFragment在扩展overrDide的片段中, overrDideonCreateDialog()是其自身公开的公共方法BottomSheetDialogFragment

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        setStyle(STYLE_NO_FRAME, R.style.BottomSheetDialog)
        return super.onCreateDialog(savedInstanceState)
    }
Run Code Online (Sandbox Code Playgroud)

除此之外,在themes.xml覆盖BottomSheetDialog主题中并添加透明背景。

    <style name="BottomSheetDialog" parent="ThemeOverlay.MaterialComponents.BottomSheetDialog">
        <item name="bottomSheetStyle">@style/BottomSheetModal</item>
    </style>

    <style name="BottomSheetModal" parent="Widget.Design.BottomSheet.Modal">
        <item name="android:background">@android:color/transparent</item>
    </style>
Run Code Online (Sandbox Code Playgroud)

更多关于:

  • BottomSheetDialogFragment这里
  • onCreateDialog这里
  • 主题BottomSheetDialog这里


Pie*_*rre 7

所以,我想出了2个解决方案.

最好的:

为您的底部工作表创建一个透明背景的活动.使用协调器布局和底部工作表实现您自己的布局.设置所需的边距.设置所需的内容.

尚未测试.

懒人:

扩展BottomSheetDialogFragment,onActivityCreated添加:

    Resources resources = getResources();

    // Set margin for Landscape Mode. Maybe a more elegant solution will be to implements our own bottom sheet with our own margins.
    if (resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        assert getView() != null;
        View parent = (View) getView().getParent();
        CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
        layoutParams.setMargins(
                resources.getDimensionPixelSize(R.dimen.bottom_sheet_margin_left), // 64dp
                0,
                resources.getDimensionPixelSize(R.dimen.bottom_sheet_margin_right), // 64dp
                0
        );
        parent.setLayoutParams(layoutParams);
    }
Run Code Online (Sandbox Code Playgroud)


小智 6

BottomSheetDialog 将从R.attr.bottomSheetDialogTheme上下文的主题中获取样式,或者使用默认的R.style.Theme_Design_Light_BottomSheetDialog.

BottomSheetDialog 的布局 xml 是R.layout.design_bottom_sheet_dialog。主要内容是一个 id/design_bottom_sheet 的 FrameLayout,其样式为?attr/bottomSheetStyle

如果您使用父级扩展样式Theme.Design.Light.BottomSheetDialog,则所有默认属性(如colorPrimary, )colorAccent可能会被覆盖。因此,建议在 View Theme 树中使用 ThemeOverlay。您应该像这样扩展样式ThemeOverlay.MaterialComponents.Light.BottomSheetDialog

<style name="Widget.Test.ButtonSheetDialogTheme" parent="ThemeOverlay.MaterialComponents.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/Widget.Test.BottomSheet.Modal</item>
</style>

<style name="Widget.Test.BottomSheet.Modal" parent="Widget.MaterialComponents.BottomSheet.Modal">
    <item name="backgroundTint">@android:color/transparent</item>
</style>
Run Code Online (Sandbox Code Playgroud)

您必须从 扩展样式Widget.MaterialComponents.BottomSheet.Modal,因为默认样式包含这些:

<style name="Widget.MaterialComponents.BottomSheet" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@null</item>
    <item name="backgroundTint">?attr/colorSurface</item>
    ....
</style>
Run Code Online (Sandbox Code Playgroud)

BottomSheetDialog 的背景由android:background和决定backgroundTint。但我不确定为什么当 android:background 为 null 时,backgroundTint 有效。??

有关Android主题的更多知识:


Con*_*nti 5

有点破解,但是它可以使背景透明。显然,您可以使用所需的任何颜色替换“透明”。

mBottomSheetDialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundResource(android.R.color.transparent);
Run Code Online (Sandbox Code Playgroud)


小智 5

回答晚了,但我自己也遇到了这个问题,并找到了比任何建议更好的解决方案。

您可以使用另一个具有透明背景的布局来包裹您的工作表布局,并从中添加边距(此处为 16dp):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/transparent"
    >
    <android.support.v4.widget.NestedScrollView
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="16dp">

        ....
Run Code Online (Sandbox Code Playgroud)

然后将透明背景添加到您的工作表中,如 Gnzlt答案中所示:

<style name="CustomBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheetStyle</item>
</style>

<style name="CustomBottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@android:color/transparent</item>
</style>
Run Code Online (Sandbox Code Playgroud)

瞧,不需要其他活动了。


小智 5

我有同样的问题,没有任何帮助。使用此代码解决问题:

  override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    val bottomSheet = (view!!.parent as View)
    bottomSheet.backgroundTintMode = PorterDuff.Mode.CLEAR
    bottomSheet.backgroundTintList = ColorStateList.valueOf(Color.TRANSPARENT)
    bottomSheet.setBackgroundColor(Color.TRANSPARENT)
}
Run Code Online (Sandbox Code Playgroud)

PS com.google.android.material:material:1.1.0-alpha09


小智 5

遵循Marco RS的想法(对我来说,这是唯一可行的解​​决方案),您可以创建一个干净的扩展并应用到您想要的对话框中的任何位置。

延期:

fun BottomSheetDialogFragment.setTransparentBackground() {
dialog?.apply {
    setOnShowListener {
        val bottomSheet = findViewById<View?>(R.id.design_bottom_sheet)
        bottomSheet?.setBackgroundResource(android.R.color.transparent)
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setTransparentBackground()
}
Run Code Online (Sandbox Code Playgroud)