-
Notifications
You must be signed in to change notification settings - Fork 5
Native shadows
Package: com.zedalpha.shadowgadgets.compose
The compose package contains two Modifier extensions (with overloads) to to
replace the inbuilt shadow.
clippedShadow behaves just like shadow, and the base
function has the exact same signature:
fun Modifier.clippedShadow(
elevation: Dp,
shape: Shape = RectangleShape,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor
)Please note that the clip parameter has nothing to do with the clipped shadow
itself. That parameter means the same thing as it does for shadow: "When
active, the content drawing clips to the shape."
If this is being used to replace the shadow on an existing Composable, it's
important to ensure that the intrinsic shadow is disabled, if it has one, by
zeroing its elevation. For example:
Card(
backgroundColor = Color.Transparent,
elevation = 0.dp,
shape = RoundedCornerShape(15.dp),
modifier = Modifier
.size(100.dp)
.clippedShadow(
elevation = 10.dp,
shape = RoundedCornerShape(15.dp)
)
) {}Color compat has been added to clippedShadow with an overload:
fun Modifier.clippedShadow(
elevation: Dp,
shape: Shape = RectangleShape,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
colorCompat: Color = DefaultShadowColor,
forceColorCompat: Boolean = false
)forceColorCompat acts like the corresponding View property to force the
compat mechanism to be used on API levels >= 28, for testing and comparisons and
whatnot.
The colorCompat parameter defaults to black, which disables the tinting, as
it's the default shadow color. If Color.Unspecified is passed, the actual
value will be blended as described below for shadowCompat.
There is also an overload that takes a lambda to allow for more efficient updates for animations and such.
fun Modifier.clippedShadow(
shape: Shape,
clip: Boolean = true,
block: ClippedShadowScope.() -> Unit
): ModifierChanging the shape or the clip will clearly need to recompose, but the rest
of the parameters – elevation, ambientColor, spotColor, colorCompat, and
forceColorCompat – now live inside ClippedShadowScope, and each can be
modified in block without causing recomposition.
The shadowCompat modifier is useful when only the color compat
functionality is needed, without the clip, in order to save some overhead:
fun Modifier.shadowCompat(
elevation: Dp,
shape: Shape = RectangleShape,
clip: Boolean = elevation > 0.dp,
ambientColor: Color = DefaultShadowColor,
spotColor: Color = DefaultShadowColor,
colorCompat: Color = Color.Unspecified,
forceColorCompat: Boolean = false
)It has the same parameter list as the clippedShadow overload, but here
colorCompat's default value is Color.Unspecified, which causes it to be
automatically calculated as a blend of the supplied ambientColor and
spotColor, in the same manner as described for ShadowColorsBlender on the
Color compat wiki page. This behavior can be
disabled by passing any other value for colorCompat.
This modifier falls back to the inbuilt shadow whenever possible,
e.g., if colorCompat is disabled, or if the resulting blend would be black.
There is a lambda overload for this function as well:
fun Modifier.shadowCompat(
shape: Shape,
clip: Boolean = true,
block: ShadowCompatScope.() -> Unit
): ModifierLike clippedShadow, changing the shape or the clip will recompose, but the
other parameters – elevation, ambientColor, spotColor, colorCompat, and
forceColorCompat – are now in ShadowCompatScope and can be updated without
recomposition.
The Compose page of the demo app has examples of clippedShadow's basic usage,
as well as demonstrations of how to replace the shadows on existing material
Composables with animated elevations – e.g., FloatingActionButton – without
having to rewrite them or fiddle with their internals.
The first color compat page is set up to demonstrate shadowCompat, with
automatic color blending too, alongside the analogous View version.
The third color compat page has a stress test setup for Compose right next to one for Views that is identical, apart from some minor irrelevant color variations, so they can be compared side by side.
Examples of both lambda versions can be found on their topic page: