BottomSheetDialog透明背景

时间:2016-05-08 21:23:29

标签: android

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

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

the Share option from Google Play Music on a Nexus 9

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

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

一些代码:

的build.gradle

compile 'com.android.support:design:23.3.0'

MainActivity

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

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>

19 个答案:

答案 0 :(得分:41)

使用BottomSheetDialogFragment时,这对我有用:

public class CustomDialogFragment extends BottomSheetDialogFragment {

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

  ...
}

同时将其添加到您的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>

答案 1 :(得分:40)

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

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

答案 2 :(得分:22)

BottomSheetDialog bottomSheetDialog =new BottomSheetDialog(this,R.style.SheetDialog);

样式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>

答案 3 :(得分:7)

所以,我找到了2个解决方案。

最好的一个:

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

尚未测试。

懒人:

onActivityCreated添加:

中扩展BottomSheetDialogFragment
    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);
    }

答案 4 :(得分:5)

对不起,您来得太晚了,如果您成功完成了,这就是您要寻找的东西

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

添加此行是最下面的对话框片段,这将达到目的

答案 5 :(得分:4)

有点破解,但它可以使背景透明化。显然你可以取代透明的&#39;用你想要的任何颜色。

mBottomSheetDialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackgroundResource(android.R.color.transparent);

答案 6 :(得分:2)

以下功能重写在svn auth 实现中起作用:

const obj = {
  hello: "world"
};
const json = JSON.stringify(obj);
const blob = new Blob([json], {
  type: 'application/json'
});
const data = new FormData();
data.append("document", blob);
axios({
  method: 'post',
  url: '/sample',
  data: data,
})

答案 7 :(得分:2)

为您的对话框实例使用“setOnShowListener”,就像在 kotlin 中这样:

        yourDialogInstance.setOnShowListener {

        //this line transparent your dialog background
        (dialogView.parent as ViewGroup).background = 
             ColorDrawable(Color.TRANSPARENT)

        }

kotlin 中的完整代码:

BottomSheetDialog(this).apply {

val dialogView = LayoutInflater.from(context)
    .inflate(R.layout.your_dialog_layout, null, false)

setContentView(dialogView)

setOnShowListener {
    (dialogView.parent as ViewGroup).background = 
             ColorDrawable(Color.TRANSPARENT)
}

show()
}

答案 8 :(得分:2)

这是你的答案:D

View contentView=LayoutInflater.from(getContext()).inflate(R.layout.bs_add_event,null);
    mBottomSheetDialog.setContentView(contentView);

    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
    params.setMargins(50,50,50,50); // set margin as your wish.

并将android:layout_width="100dp" in nestedScroolView更改为  android:layout_width="match_parent"

答案 9 :(得分:1)

我知道这个问题很旧,但是我仍然回答该问题,并希望它有用。 默认情况下,在onCreateView()方法中指定的布局将被FrameLayout添加到白色背景的BottomSheetDialogFragment。因此,您应该使用onStart()方法将FrameLayout的背景设置为透明。

class YourDialog() : BaseBottomDialog() {
   
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.layout_your_dialog, container, false)
    }
    override fun onStart() {
        super.onStart()
        (view!!.parent as View).setBackgroundColor(Color.TRANSPARENT)
    }
}

答案 10 :(得分:1)

最新答案,但是我自己遇到了这个问题,并且找到了比建议的更好的解决方案。

您可以将工作表布局与具有透明背景的其他布局包装在一起,并从中添加边距(此处为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">

        ....

然后将透明背景添加到工作表中,就像在Gnzlt answer中一样:

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

瞧,不需要其他活动。

答案 11 :(得分:1)

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

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

如果您使用父级 Theme.Design.Light.BottomSheetDialog 扩展样式,那么您的所有默认属性(如 colorPrimarycolorAccent)可能会被覆盖。因此建议在查看主题树中使用 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>

您必须从 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>

BottomSheetDialog 的背景由 android:backgroundbackgroundTint 共同决定。但我不确定为什么 backgroundTint 在 android:background 为空时有效。 ???

有关 Android 主题的更多知识:

答案 12 :(得分:0)

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

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

P.S。 com.google.android.material:material:1.1.0-alpha09

答案 13 :(得分:0)

这对我有用。.Oncreate对话框获取窗口设置颜色

public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    if(dialog.getWindow() !=null){
        dialog.getWindow().setGravity(Gravity.BOTTOM);
        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
        dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        dialog.setCancelable(false);
    }
    return dialog;
}

答案 14 :(得分:0)

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

扩展名:

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

示例:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setTransparentBackground()
}

答案 15 :(得分:0)

如果您使用的是BottomSheetBehavior,则对折叠和展开状态使用以下代码

behavior.setState(BottomSheetBehavior.STATE_EXPANDED);             ((View)getParent()).setBackgroundColor(getResources().getColor(<your desire color>));

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); ((View).getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));

还要使用

 behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                    ((View) mScrollview.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
                }
            }
            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                // React to dragging events  
            }
        });

答案 16 :(得分:0)

如果您希望所有 BottomSheets 都继承该行为,请执行以下操作:

<style name="Theme.InstaDownloader" parent="Theme.MaterialComponents.Light.NoActionBar">
       ...
        <item name="bottomSheetDialogTheme">@style/BottomSheetTheme</item>
       ...
 </style>

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

 <style name="BottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
        <item name="android:background">@android:color/transparent</item>
 </style>

答案 17 :(得分:0)

有几种hackish方法可以做到这一点。我解决这个问题的方式是推荐的方式。让我们明白为什么?

在文档中,提到了

<块引用>

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

这意味着应该有一个 BottomSheetDialogFragment 用来将默认 Dialog 替换为 BottomSheetDialog 的方法。

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

推荐方法

在扩展 BottomSheetDialogFragment overrDide onCreateDialog() 的片段中,这是一个由 BottomSheetDialogFragment 本身公开的公共方法。

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

除此之外,在 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>

更多关于:

  • BottomSheetDialogFragmenthere
  • onCreateDialoghere
  • 主题化BottomSheetDialoghere

答案 18 :(得分:0)

发现我需要在已接受的答案上使用一个变体,方法是更新到 MaterialComponents 以使其与 AndroidX 兼容并添加“backgroundTint”作为透明:

<style name="BottomSheetDialog" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/BottomSheetDialogStyle</item>
</style>

<style name="BottomSheetDialogStyle" parent="Widget.MaterialComponents.BottomSheet.Modal">
    <item name="android:background">@android:color/transparent</item>
    <item name="android:backgroundTint">@android:color/transparent</item>
</style>

按照原始答案将“BottomSheetDialog”样式应用于片段:

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