如何实现BottomSheetDialog中MaterialCardView仅顶部圆角效果?
解决BottomSheetDialog中MaterialCardView仅顶部圆角的问题
需求
仅让BottomSheetDialog中的MaterialCardView顶部左右两角为圆角,底部保持直角。
已尝试方案
- 使用Glide加载图片时,通过
GranularRoundedCorners设置ImageView顶部圆角 - 在BottomSheetDialog的
onCreate方法中设置自定义样式@style/TopRoundedBottomSheetDialog
上述方案均未达成预期效果。
相关代码
layout.xml
<com.google.android.material.card.MaterialCardView android:id="@+id/cardViewInfo" android:layout_width="match_parent" style="@style/CustomCardViewCornerStyle" android:layout_height="wrap_content" android:background="@color/red_no" android:clickable="true" android:focusable="true" app:cardElevation="5dp"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/imageViewPhoto" android:layout_width="match_parent" android:minHeight="200dp" android:layout_height="160dp" android:scaleType="center" app:layout_constraintDimensionRatio="h,375:240" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/imageViewCross" android:layout_width="48dp" android:layout_height="48dp" android:padding="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_close_btn" /> <matas.matas.core.control.TextViewInterRegular android:id="@+id/textViewExpiryDate" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginTop="24dp" android:layout_marginEnd="24dp" android:gravity="center_horizontal" android:textColor="@color/colorBlackLight" android:textSize="10sp" android:lineHeight="12sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageViewPhoto" tools:text="Udløber xx.xx.xxxx" /> <matas.matas.core.control.TextViewDMSerifRegular android:id="@+id/textViewName" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:layout_marginTop="6dp" android:gravity="start" android:textColor="@color/black" android:textSize="24sp" android:lineHeight="28.8sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/textViewExpiryDate" tools:text="40% på Striberne" /> <matas.matas.core.control.TextViewInterSemiBold android:id="@+id/textViewTeaserText" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginTop="16dp" android:layout_marginEnd="24dp" android:gravity="left" android:textColor="@color/black" android:textSize="14sp" android:lineHeight="21sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textViewName" tools:text="Du i hele februar 40% på ALLE produkter fra Matas striber." /> <matas.matas.core.control.TextViewInterRegular android:id="@+id/textViewDisclaimerPlus" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:layout_marginBottom="16dp" android:gravity="start" android:textColor="@color/colorBlackLight" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textViewTeaserText" app:layout_constraintBottom_toBottomOf="parent" tools:text="Kontakt en materialist her i butikken og vis dit medlemskort, så får du rabatten på dit køb" /> <matas.matas.core.control.TextViewInterRegular android:id="@+id/textViewDisclaimerNonPlus" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:layout_marginBottom="16dp" android:gravity="start" android:textColor="@color/colorBlackLight" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textViewTeaserText" app:layout_constraintBottom_toBottomOf="parent" tools:text="Kontakt en materialist her i butikken og vis dit medlemskort, så får du rabatten på dit køb" /> </androidx.constraintlayout.widget.ConstraintLayout> </com.google.android.material.card.MaterialCardView>
已尝试的Glide代码
Glide.with(binding.imageViewPhoto) .load(url) .transform(GranularRoundedCorners(120.0f,120.0f,0.0f,0.0f)) .into(binding.imageViewPhoto)
已尝试的Dialog样式设置代码
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setStyle(STYLE_NORMAL, matas.matas.core.R.style.TopRoundedBottomSheetDialog) }
可行解决方案
方案一:直接配置MaterialCardView的顶部圆角
MaterialCardView原生支持细粒度圆角控制,无需依赖其他组件,可通过布局或代码实现:
布局静态配置
在MaterialCardView标签中添加app:shapeAppearanceOverlay属性,指向自定义样式:
<com.google.android.material.card.MaterialCardView ... app:shapeAppearanceOverlay="@style/CardTopRoundedCorners" <!-- 移除android:background,改用CardView自带的cardBackgroundColor设置背景色 --> app:cardBackgroundColor="@color/red_no">
在styles.xml中定义该样式:
<style name="CardTopRoundedCorners" parent=""> <item name="cornerFamily">rounded</item> <item name="cornerSizeTopLeft">16dp</item> <!-- 替换为你需要的圆角尺寸 --> <item name="cornerSizeTopRight">16dp</item> <item name="cornerSizeBottomLeft">0dp</item> <item name="cornerSizeBottomRight">0dp</item> </style>
代码动态配置
若需动态调整圆角大小,可在Dialog初始化后执行:
// 构建自定义ShapeAppearanceModel val shapeModel = binding.cardViewInfo.shapeAppearanceModel.toBuilder() .setTopLeftCorner(CornerFamily.ROUNDED, dpToPx(16)) .setTopRightCorner(CornerFamily.ROUNDED, dpToPx(16)) .setBottomLeftCorner(CornerFamily.ROUNDED, 0f) .setBottomRightCorner(CornerFamily.ROUNDED, 0f) .build() binding.cardViewInfo.shapeAppearanceModel = shapeModel // 辅助函数:dp转px private fun dpToPx(dp: Int): Float { return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), resources.displayMetrics ) }
方案二:修复BottomSheetDialog样式设置
若坚持通过Dialog样式实现,需确保样式正确覆盖BottomSheet的背景和圆角:
在styles.xml中完善样式定义:
<style name="TopRoundedBottomSheetDialog" parent="Theme.MaterialComponents.BottomSheetDialog"> <item name="bottomSheetStyle">@style/TopRoundedBottomSheet</item> </style> <style name="TopRoundedBottomSheet" parent="Widget.MaterialComponents.BottomSheet"> <item name="shapeAppearanceOverlay">@style/CardTopRoundedCorners</item> <!-- 设置背景透明,避免遮挡CardView的圆角 --> <item name="android:background">@android:color/transparent</item> </style>
同时移除MaterialCardView的android:background属性,改用app:cardBackgroundColor设置背景色,避免覆盖CardView的圆角效果。
失效原因分析
- Glide仅设置了ImageView的圆角,MaterialCardView自身的直角边框仍会显示,导致视觉不符合预期。
- 之前的Dialog样式未正确配置BottomSheet的背景透明,或CardView的
android:background属性覆盖了样式的圆角效果。
内容的提问来源于stack exchange,提问作者Taimoor Khan
相关产品推荐
相关产品推荐

