BottomSheetDialogFragment的圆角

Ras*_*ana 48 android material-design bottom-sheet material-components material-components-android

我有一个自定义的BttomSheetDialogFragment,我希望在底部视图的顶部有圆角

这是我的自定义类,它让我希望从底部显示我的布局

View mView;

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

我也有这个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"/>
Run Code Online (Sandbox Code Playgroud)

但问题是,当我将此资源文件设置为我的Layout的根元素的背景时,角落仍然没有舍入

我不能使用下面的代码:

    this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);
Run Code Online (Sandbox Code Playgroud)

因为它覆盖BottomSheetDialog的默认背景,并且在我的底视图上方不会有任何半透明的灰色

小智 115

创建自定义drawable 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>
Run Code Online (Sandbox Code Playgroud)

然后覆盖bottomSheetDialogThemestyles.xml使用可绘制背景:

<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>
Run Code Online (Sandbox Code Playgroud)

这将更改您应用的所有BottomSheetDialog.

  • 请注意,如果您在根视图上指定背景,那么这将覆盖此设置 (8认同)
  • 确保工作表布局的根元素上没有任何背景! (5认同)
  • 这么多步骤只是为了添加圆角......不过感谢您发布此内容。 (4认同)
  • 这个对我有用。我还注意到它取决于布局根元素。首先我将cardview作为root(因为我尝试了另一种圆角的方法),然后我将其更改为线性布局,现在它可以完美运行 (2认同)

ak9*_*k93 25

对我来说最简单、最干净的解决方案是将以下 4 行放入片段类的 onViewCreated(View view, Bundle savingInstanceState) 方法中:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    View bottomSheet = (View) view.getParent();
    bottomSheet.setBackgroundTintMode(PorterDuff.Mode.CLEAR);
    bottomSheet.setBackgroundTintList(ColorStateList.valueOf(Color.TRANSPARENT));
    bottomSheet.setBackgroundColor(Color.TRANSPARENT);
}
Run Code Online (Sandbox Code Playgroud)

一旦设置为片段布局的顶级视图的背景,这将允许您的带有圆角的自定义可绘制对象正确显示。

本质上,这会覆盖有关颜色、tintMode 和tintList 的默认BottomSheetFragment 属性。

使用此功能,无需弄乱样式资源。

  • 只有一个对我有用,上面那些有更多赞成票的花哨的东西工作量太大,根本不起作用,而且如果 ypu 有不同的背景颜色,那就很复杂,只需添加一个带有圆角边缘的圆形背景可绘制并添加您的代码,就像魅力! (2认同)

Bad*_*adr 20

BottomSheetDialog被设置默认的白色背景颜色,这就是为什么角落是不可见的,为了向他们展示你需要做的对话框通过重写的风格的背景透明BottomSheetDialog.

定义这种风格在你的 res/values/styles/styles.xml

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

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

并将此样式设置为BottomSheetDialog

View view = getLayoutInflater().inflate(R.layout.chooser_bottom_sheet, null);
BottomSheetDialog dialog = new BottomSheetDialog(this,R.style.BottomSheetDialog); // Style here
dialog.setContentView(view);
dialog.show();
Run Code Online (Sandbox Code Playgroud)

  • 比接受的答案更好,因为这样你可以在不同的 BottomSheetDialogs 上有不同的背景 (2认同)
  • 优雅的解决方案 (2认同)

小智 14

它对我有用

创建一个名为 shape_rounded_dialog 的形状

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_white" />
<corners
    android:topLeftRadius="16dp"
    android:topRightRadius="16dp" />
Run Code Online (Sandbox Code Playgroud)

添加以下样式

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

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

在 DialogFragment 类中,方法覆盖 getTheme 也返回 Yourself 样式。

@Override
public int getTheme() {
    return R.style.AppBottomSheetDialogTheme;
}
Run Code Online (Sandbox Code Playgroud)


Zai*_*ain 14

2023 年 10 月编辑:针对 Material3

最初的答案方法仍然适用于 Material 3,但它有像素化的角,因此这里有另一种方法来解决 Materia3 的问题:

  1. 创建一个 Material3 BottomSheet 样式:
<style name="RoundedBackgroundBottomSheetDialog" parent="@style/ThemeOverlay.Material3.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/RoundedCornerStyle</item>
</style>

<style name="RoundedCornerStyle" parent="Widget.Material3.BottomSheet">
    <item name="dialogCornerRadius">16dp</item>
    <item name="android:backgroundTint">@color/dialog_background</item>
</style>
Run Code Online (Sandbox Code Playgroud)

@color/dialog_background是工作表背景颜色。

  1. 将样式应用到您的BottomSheetDialogFragment
class MyDialogFragment : BottomSheetDialogFragment() {

    override fun getTheme() = R.style.RoundedBackgroundBottomSheetDialog
    
    .... 

}
Run Code Online (Sandbox Code Playgroud)

原答案

步骤1:

创建一个res/drawable名为rounded_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners
    android:topLeftRadius="32dp"
    android:topRightRadius="32dp" />
  <solid android:color="#D81B60" />
</shape>
Run Code Online (Sandbox Code Playgroud)

第2步:

创建此样式以删除对话框背景:

<style name="NoBackgroundDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="android:windowBackground">@null</item>
</style>
Run Code Online (Sandbox Code Playgroud)

步骤3:

setBackgroundResource()使用并通过覆盖getTheme()方法设置样式将可绘制对象设置为对话框的根视图

爪哇:

public class MyDialogFragment extends BottomSheetDialogFragment {

    @Override
    public int getTheme() {
        return R.style.NoBackgroundDialogTheme;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = View.inflate(requireContext(), R.layout.bottom_sheet_profile, null);
        view.setBackgroundResource(R.drawable.rounded_background);
        return view;

    }
}
Run Code Online (Sandbox Code Playgroud)

科特林:

class MyDialogFragment : BottomSheetDialogFragment() {

    override fun getTheme() = R.style.NoBackgroundDialogTheme

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        val view: View = View.inflate(requireContext(), R.layout.bottom_sheet_profile, null)
        view.setBackgroundResource(R.drawable.rounded_background)
        return view
    }

}
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

if( view.setBackgroundResource(R.drawable.rounded_background)) 这行不起作用,然后尝试设置 Xml 格式片段的背景。


Ben*_*det 12

如果您使用最新版本的材料组件,您只需覆盖ShapeAppearance.MaterialComponents.LargeComponent(因为底部工作表使用此形状)并设置您想要的值,例如:

 <style name="ShapeAppearance.YourApp.LargeComponent" parent="ShapeAppearance.MaterialComponents.LargeComponent">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSize">12dp</item>
 </style>
Run Code Online (Sandbox Code Playgroud)

然后在您的应用程序样式中设置:

<item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.YourApp.LargeComponent</item>
Run Code Online (Sandbox Code Playgroud)

Gabriele Mariotti 的解决方案类似并且也有效,但这个更简单。

  • 请注意:使用此答案将导致所有使用“ShapeAppearance.MaterialComponents.LargeComponent”的组件具有相同的角尺寸和系列,而不仅仅是底板。检查您的样式要求并决定是否要更改所有组件或仅单个组件或小部件的外观。 (3认同)

Gab*_*tti 11

借助新的Material Component库,您可以使用样式中的属性来自定义组件的形状shapeAppearanceOverlay

只需使用BottomSheetDialogFragment覆盖onCreateView方法,然后为“底表对话框”定义自定义样式。

在您的应用主题中定义bottomSheetDialogTheme属性styles.xml

  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.MaterialComponents.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    ....
    <item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
  </style>
Run Code Online (Sandbox Code Playgroud)

然后只需定义您喜欢的形状 shapeAppearanceOverlay

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

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

  <style name="CustomShapeAppearanceBottomSheetDialog" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">16dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomRight">0dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
  </style>
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

它需要版本1.1.0(当前最新版本是1.1.0-beta02)。

  • 这是完美且最新的答案。我需要将此标记为答案 (7认同)
  • 我在 v1.1.0-beta02“无法膨胀行为子类 com.google.android.material.bottomsheet.BottomSheetBehavior”上收到此错误并崩溃 (6认同)
  • 如果底部工作表对话框展开,则它不起作用。任何想法? (5认同)
  • 已找到一种方法,即使在 1.1.0 版本的展开状态下也能具有圆角。刚刚添加了透明_backgroundTint_。`&lt;style name="CustomBottomSheetDialog"parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog"&gt; &lt;item name="bottomSheetStyle"&gt;@style/CustomBottomSheet&lt;/item&gt; &lt;item name="android:backgroundTint"&gt;@color/透明&lt;/item&gt; &lt;/style&gt;` (5认同)
  • 这很简洁,但对我来说似乎不起作用。 (3认同)

Aas*_*gar 8

今天我正在检查同样的事情,是的,你是关于遵循代码的

this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);
Run Code Online (Sandbox Code Playgroud)

这适用于片段背景,因此您应该从对话框窗口获取底部视图,并在此处更改背景是代码

 @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);
    }
Run Code Online (Sandbox Code Playgroud)

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


Min*_*hip 8

  1. 创建一个可绘制的形状 .. 我们将使用它作为底片的背景。为左上角和右上角的半径提供适当的值。

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners
            android:topLeftRadius="24dp"
            android:topRightRadius="24dp" />
        <padding android:top="2dp" />
        <solid android:color="@color/white" />
    </shape>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在为“底部工作表对话框片段”创建样式

    <style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
            <item name="android:background">@drawable/drawable_bottomsheet_background</item>
        </style>
    
        <style name="BaseBottomSheetDialog" parent="@style/Theme.Design.Light.BottomSheetDialog">
            <item name="android:windowIsFloating">false</item>
            <item name="bottomSheetStyle">@style/BottomSheet</item>
        </style>
    
        <style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />
    
    Run Code Online (Sandbox Code Playgroud)
  3. 现在创建一个自定义类,该类将扩展 BottomSheetDilogFragment,您可以在其中提供您的样式。

    open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
    
        override fun getTheme(): Int = R.style.BottomSheetDialogTheme
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 现在在任何你想要圆角底片的地方使用这个类。例如

    class BottomSheetSuccess : CustomRoundBottomSheet() {
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(R.layout.bottomsheet_shopcreate_success, container, false)
        }
    
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
        }
    
    } 
    
    Run Code Online (Sandbox Code Playgroud)


DYS*_*DYS 8

简单的解决方案:

class TopRoundedCornersFragment : BottomSheetDialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setStyle(STYLE_NORMAL, R.style.AppBottomSheetDialogTheme)
    }
}
Run Code Online (Sandbox Code Playgroud)

在 styles.xml 中

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

<style name="AppBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/BottomSheetStyle</item>
</style>
Run Code Online (Sandbox Code Playgroud)

最后,创建一个顶部圆角可绘制资源(bottom_sheet_dialog_bg.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@android:color/white" />
    <corners
        android:topLeftRadius="4dp"
        android:topRightRadius="4dp" />

</shape>
Run Code Online (Sandbox Code Playgroud)


Var*_*iag 7

通过回答科马业另一个问题为我工作,你应该尝试一下。

在drawable中创建一个xml,例如dialog_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white"/>
    <corners android:radius="30dp" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
</shape>
Run Code Online (Sandbox Code Playgroud)

将其放在布局xml根节点中:

将其设置为布局xml中的背景

android:background="@drawable/dialog_bg"
Run Code Online (Sandbox Code Playgroud)

onCreateView()把这个:

将对话框的背景设置为透明

dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Run Code Online (Sandbox Code Playgroud)

  • **对我来说,圆角后面仍然有白色角。**因此,当我将可绘制的颜色更改为红色时,您的代码可以正常工作并创建一个圆角的红色矩形,但是在其后面仍然有一个默认的白色矩形。您编写的_“ dialog.getWindow()。setBackgroundDrawable ...” _代码更改了对话框上方整个“变暗”区域的颜色,但同样,它错过了这两个小角。**您知道什么可能导致此问题吗?** (2认同)

zhi*_*min 7

创建一个名为rounded_corners_shape的形状

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

</shape>
Run Code Online (Sandbox Code Playgroud)

定义风格

  <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_corners_shape</item>
    </style>
Run Code Online (Sandbox Code Playgroud)

像这样在自定义BottomSheetDialogFragment上使用这种样式,就可以了!

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

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


abh*_*swa 5

我知道这个问题已经有一个公认的答案。我想记录我遇到的问题以及我最终如何让它发挥作用,以便对未来的人有用。

首先,我使用Theme.AppCompat.Light.DarkActionBar作为我们的父级AppTheme。这意味着 @Gabriele Mariotti 解决方案不断因错误而崩溃Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior。我通过简单地将父级更改为 来解决此问题Theme.MaterialComponents.Light.DarkActionBar。这并没有以任何方式影响我们的主题,但 RTE 消失了。您还可以通过简单地将必需的项目包含到您的样式中来解决此问题。但我没有费心去弄清楚 BottomSheetBehavior 需要哪些样式。

其次,尽我所能,但我无法获得实际的框架布局(即 BottomSheetDialogFragment)使用的圆角。我意识到将其设置为可绘制图像可以工作,但不能使用形状或@null. 事实证明,这是因为LinearLayout我使用的背景已定义。这压倒了该风格的任何背景。删除它最终导致圆角。

另外,我不需要将任何背景形状设置为圆角。当我进行上述更改后,@Gabriele Mariotti 的解决方案就起作用了。然而,为了设置我想要的背景颜色,我必须覆盖“backgroundTint”项。

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