Last active
November 4, 2020 19:36
-
-
Save kazukinr/e8f90a3eb22a59ea2362091e22566e6c to your computer and use it in GitHub Desktop.
A simple implementation of FrameLayout with rounded corners.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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