Skip to content

Instantly share code, notes, and snippets.

@kazukinr
Last active November 4, 2020 19:36
Show Gist options
  • Save kazukinr/e8f90a3eb22a59ea2362091e22566e6c to your computer and use it in GitHub Desktop.
Save kazukinr/e8f90a3eb22a59ea2362091e22566e6c to your computer and use it in GitHub Desktop.
A simple implementation of FrameLayout with rounded corners.
package com.github.kazukinr.samole.android.widget
import android.content.Context
import android.graphics.Canvas
import android.graphics.Outline
import android.graphics.Path
import android.graphics.RectF
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.FrameLayout
import androidx.annotation.RequiresApi
class RoundedCornersFrameLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
companion object {
private const val CORNER_RADIUS_DP = 4
}
// You can set cornerRadius by attrs or BindingAdapter as you like.
private val cornerRadius = context.resources.displayMetrics.density * CORNER_RADIUS_DP
private var path: Path? = null
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// For Lollipop or later, we can use ViewOutlineProvider to clip.
outlineProvider = OutlineProvider(cornerRadius)
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Path().also {
it.addRoundRect(RectF(0f, 0f, w.toFloat(), h.toFloat()), cornerRadius, cornerRadius, Path.Direction.CW)
path = it
}
}
}
override fun dispatchDraw(canvas: Canvas) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
path?.also {
val saved = canvas.save()
canvas.clipPath(it)
super.dispatchDraw(canvas)
canvas.restoreToCount(saved)
return
}
}
super.dispatchDraw(canvas)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private class OutlineProvider(private val radius: Float) : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, radius)
view.clipToOutline = true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment