-
-
Save xvadsan/a6669d23314b8a64d75742e677a225fe to your computer and use it in GitHub Desktop.
Part 2 of blog post - Control view's shadow
This file contains 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
fun View.setShadow( | |
@ColorRes shadowColor: Int, | |
@DimenRes cornerRadius: Int, | |
@DimenRes elevation: Int, | |
shadowGravity: Int = Gravity.BOTTOM, | |
@ColorRes backgroundColorResource: Int = 0 | |
) { | |
val resource = context.resources | |
val firstLayer = 0 | |
val ratioTopBottom = 3 | |
val defaultRatio = 2 | |
if (background == null && backgroundColorResource == 0) { | |
throw RuntimeException("Pass backgroundColorResource or use setBackground") | |
} | |
if (background != null && background !is ColorDrawable) { | |
throw RuntimeException( | |
"${background::class.java.name} " + | |
"is not supported, set background as " + | |
"ColorDrawable or pass background as a resource" | |
) | |
} | |
val cornerRadiusValue = resource.getDimension(cornerRadius) | |
val elevationValue = resource.getDimension(elevation).toInt() | |
val shadowColorValue = ContextCompat.getColor(context, shadowColor) | |
val backgroundColor = if (backgroundColorResource != 0) { | |
ContextCompat.getColor(context, backgroundColorResource) | |
} else { | |
(background as ColorDrawable).color | |
} | |
val outerRadius = FloatArray(8) { cornerRadiusValue } | |
val directionOfY = when (shadowGravity) { | |
Gravity.CENTER -> 0 | |
Gravity.TOP -> -1 * elevationValue / ratioTopBottom | |
Gravity.BOTTOM -> elevationValue / ratioTopBottom | |
else -> elevationValue / defaultRatio // Gravity.LEFT & Gravity.RIGHT | |
} | |
val directionOfX = when (shadowGravity) { | |
Gravity.LEFT -> -1 * elevationValue / ratioTopBottom | |
Gravity.RIGHT -> elevationValue / ratioTopBottom | |
else -> 0 | |
} | |
val shapeDrawable = ShapeDrawable() | |
shapeDrawable.paint.color = backgroundColor | |
shapeDrawable.paint.setShadowLayer( | |
cornerRadiusValue / ratioTopBottom, | |
directionOfX.toFloat(), | |
directionOfY.toFloat(), | |
shadowColorValue | |
) | |
shapeDrawable.shape = RoundRectShape(outerRadius, null, null) | |
when (Build.VERSION.SDK_INT) { | |
in Build.VERSION_CODES.BASE..Build.VERSION_CODES.O_MR1 -> setLayerType( | |
View.LAYER_TYPE_SOFTWARE, | |
shapeDrawable.paint | |
) | |
} | |
val drawable = LayerDrawable(arrayOf(shapeDrawable)) | |
drawable.setLayerInset( | |
firstLayer, | |
elevationValue, | |
elevationValue * defaultRatio, | |
elevationValue, | |
elevationValue * defaultRatio | |
) | |
background = drawable |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment