我有一个自定义的bittomsheetdialogfragment,我想在底部视图的顶部有圆角

这是我的自定义类,它膨胀了我想要从底部显示的布局

View mView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mView = inflater.inflate(R.layout.charge_layout, container, false);
    initChargeLayoutViews();
    return mView;
}

我还有这个XML资源文件作为背景:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <corners android:topRightRadius="35dp"
        android:topLeftRadius="35dp"
        />
    <solid android:color="@color/white"/>

    <padding android:top="10dp"
        android:bottom="10dp"
        android:right="16dp"
        android:left="16dp"/>
</shape>

问题是,当我把这个资源文件设置为我的布局的根元素的背景,角仍然不是圆角。

我不能使用以下代码:

this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);

因为它覆盖了底部对话框的默认背景,底部视图上方不会有任何半透明的灰色。


当前回答

创建一个自定义的圆角绘图,并将其设置为你的BottomSheetDialogFragment的布局根的背景

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@color/colorPrimary" />

<corners
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    android:topLeftRadius="12dp"
    android:topRightRadius="12dp" />

</shape>

然后简单地将下面的代码添加到您的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(ContextCompat.getColor(getContext(), android.R.color.transparent));
}

你甚至可以像下面这样使用参数来设置边距

params.setMargins(50, 0, 50, 0);

其他回答

创建一个自定义绘制的rounded_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white"/>
    <corners android:topLeftRadius="16dp"
        android:topRightRadius="16dp"/>

</shape>

然后在styles.xml上使用drawable作为背景覆盖bottomSheetDialogTheme:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">       
    <item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
</style>

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

<style name="AppModalStyle"
    parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@drawable/rounded_dialog</item>
</style>

这将改变你的应用程序的所有底部对话框。

我知道这个问题已经有了一个公认的答案。我想要记录我经历的问题,以及我最终是如何让它工作的,这样它对未来的人是有用的。

Firstly, I was using Theme.AppCompat.Light.DarkActionBar as the parent for our AppTheme. This meant @Gabriele Mariotti solution kept crashing with the error Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior. I fixed this by simply changing the parent to Theme.MaterialComponents.Light.DarkActionBar. This did not affect our theme in any way but the RTE was gone. You can also fix this issue by simply including the require items to your style. But I didn't bother figuring out which styles were required by BottomSheetBehavior.

其次,尝试我可能,但我不能得到实际的框架布局(这是BottomSheetDialogFragment)使用圆角。我意识到,将此设置为图像Drawable工作,但不适用于形状或@null。事实证明,这是因为我使用的LinearLayout有一个定义的背景。这覆盖了样式中的任何背景。去掉它最终会产生圆角。

此外,我不需要设置任何背景形状来圆角。@Gabriele Mariotti的解决方案在我做出上述更改后立即起作用。然而,为了设置我想要的背景色,我必须覆盖“backgroundTint”项。

PS:我是Android开发的新手,我正在维护一个旧的应用程序,这是我们学院内部使用的。我不是很熟悉Android的布局系统或材料库。我想这就是为什么我花了3天时间才弄明白。我希望这对将来的人有用。

正如在其他答案中指出的,当state为BottomSheetBehavior时。STATE_EXPANDED角将被压平。

你可以通过设置BottomSheetBehavior的peekHeight属性并使用自定义样式来克服这个问题。

abstract class BaseBottomSheetFragment : BottomSheetDialogFragment(){

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
        if (state == BottomSheetBehavior.STATE_EXPANDED) {
            val displayMetrics = DisplayMetrics()
            requireActivity().windowManager!!.defaultDisplay!!.getMetrics(displayMetrics)
            (dialog as BottomSheetDialog).behavior.peekHeight = displayMetrics.heightPixels
        } else {
            (dialog as BottomSheetDialog).behavior.state = state
        }
    }

    override fun getTheme(): Int {
        return R.style.CustomBottomSheetDialog
    }
}

CustomBottomSheetDialog风格

<style name="CustomBottomSheetDialog" parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheet</item>
    <item name="materialButtonStyle">@style/CustomMaterialButtonStyle</item>
</style>

<style name="CustomMaterialButtonStyle" parent="@style/Widget.MaterialComponents.Button">
    <item name="cornerRadius">@dimen/dialog_bottom_radius</item>
</style>

<style name="CustomBottomSheet" parent="Widget.MaterialComponents.BottomSheet">
    <item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
</style>

<style name="CustomShapeAppearanceBottomSheetDialog" parent="">
    <item name="android:background">@android:color/transparent</item>
    <item name="backgroundTint">@android:color/transparent</item>
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">@dimen/dialog_bottom_radius</item>
    <item name="cornerSizeTopLeft">@dimen/dialog_bottom_radius</item>
    <item name="cornerSizeBottomRight">0dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
</style>

我今天也检查了同样的事情,是的,你是对的,下面的代码

this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);

这适用于片段背景,所以相反,你应该从对话框窗口获得底部表视图,并改变背景,这里是代码

 @SuppressLint("RestrictedApi")
    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View rootView = getActivity().getLayoutInflater().inflate(R.layout.view_member_info,null,false);
        unbinder = ButterKnife.bind(this, rootView);
        adjustUIComponents();
        dialog.setContentView(rootView);
        FrameLayout bottomSheet = (FrameLayout) dialog.getWindow().findViewById(android.support.design.R.id.design_bottom_sheet);
        bottomSheet.setBackgroundResource(R.drawable.container_background);
    }

这里的底部是你想要改变的实际视图。

在STATE_EXPANDED上禁用圆角平化的短解决方案:

@SuppressLint("RestrictedApi")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = super.onCreateDialog(savedInstanceState)
    
    //Disable animator that flats the rounded corners
    (dialog as BottomSheetDialog).behavior.disableShapeAnimations()

    return dialog
}