Skip to content

Instantly share code, notes, and snippets.

@Benjiko99
Created May 2, 2023 12:06
Show Gist options
  • Save Benjiko99/c6e03590d7d71f28e0fbf7a8bd5f0983 to your computer and use it in GitHub Desktop.
Save Benjiko99/c6e03590d7d71f28e0fbf7a8bd5f0983 to your computer and use it in GitHub Desktop.
A CardView that supports clipping content of non-uniform shapes. [MaterialCardView] doesn't round corners on older devices when all corners aren't equal in shape and size.
val cardView: MaskedCardView
fun usageExample() {
// Each corner can have a different radius
val shapeBuilder = cardView.shapeAppearanceModel.toBuilder()
.setTopLeftCornerSize(AbsoluteCornerSize(dpToPx(12f)))
.setBottomRightCornerSize(AbsoluteCornerSize(dpToPx(6f)))
cardView.shapeAppearanceModel = shapeBuilder.build()
// [MaterialCardView] disables content clipping if all corners aren't equal in shape and size,
// we can safely enable it again whenever we set a new shapeAppearanceModel.
cardView.clipToOutline = true
}
/**
* A CardView that supports clipping content of non-uniform shapes.
*
* [MaterialCardView] doesn't round corners on older devices when all corners aren't equal in shape and size.
*
* Based on [github.com/android/sunflower](https://github.com/android/sunflower/blob/main/app/src/main/java/com/google/samples/apps/sunflower/views/MaskedCardView.kt)
*/
open class MaskedCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = R.attr.materialCardViewStyle
) : MaterialCardView(context, attrs, defStyle) {
@SuppressLint("RestrictedApi")
private val pathProvider = ShapeAppearancePathProvider()
private val maskPath = Path()
private val maskBounds = RectF()
override fun onDraw(canvas: Canvas) {
canvas.clipPath(maskPath)
super.onDraw(canvas)
}
@SuppressLint("RestrictedApi")
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (w != oldw || h != oldh) {
maskBounds.right = w.toFloat()
maskBounds.bottom = h.toFloat()
pathProvider.calculatePath(shapeAppearanceModel, 1f, maskBounds, maskPath)
}
}
override fun setShapeAppearanceModel(shapeAppearanceModel: ShapeAppearanceModel) {
super.setShapeAppearanceModel(shapeAppearanceModel)
pathProvider.calculatePath(shapeAppearanceModel, 1f, maskBounds, maskPath)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment