https://kotlinlang.org logo
#compose
Title
# compose
k

karandeep singh

05/02/2020, 7:20 PM
An attempt to create a shimmer effect in compose. currently implemented using canvas and linear gradient. Would love to know if there could be a better/efficient way to do this.
👍 10
z

Zach Klippenstein (he/him) [MOD]

05/02/2020, 8:49 PM
Would you mind sharing your code? This looks good!
l

Leland Richardson [G]

05/02/2020, 9:01 PM
Since Karan asked, I took a stab at improving it a bit: https://gist.github.com/lelandrichardson/35b2743e1acd5d672f963f92aca57d4a
👍 4
r

romainguy

05/02/2020, 9:42 PM
We need to fix that name
isAntiAlias
isAntiAliased
, sure;
hasAntiAliasing
, sure;
antiAlias/ing
, sure
1
isAntiAlias
, 🙅
BTW there’s also a way to do with no allocations. Linear gradient shaders (at least in
android.graphics
) accept a local transform as a
Matrix
which you can
setTranslate(x,y)
on every frame. If you set the shader’s tile mode to
CLAMP
you’re good to go
🎉 2
l

Leland Richardson [G]

05/02/2020, 9:48 PM
ah, good call. i was trying to figure out how to avoid that allocation and couldnt
k

karandeep singh

05/03/2020, 5:44 PM
@Leland Richardson [G] can you please tell what is composed here?
fun Modifier.shimmer() = composed {
val progress = animatedFloat(0f)
onActive {
progress.loop(0f, 1f, 1000)
onDispose {
progress.stop()
}
}
remember { ShimmerModifier(progress) }
}
z

Zach Klippenstein (he/him) [MOD]

05/03/2020, 6:22 PM
I was wondering that too, it looks like a relatively new thing that lets modifiers be stateful without requiring the user to invoke a composable factory function at the use site: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:ui/ui-core/src/main/java/androidx/ui/core/ComposedModifier.kt;l=31;bpv=1
k

karandeep singh

05/03/2020, 6:27 PM
not part of dev10 version as well 😛
l

Leland Richardson [G]

05/03/2020, 6:55 PM
yeah, sorry, that’s a new API 🙂
you can just change it to
@Composable fun Modifier.shimmer() = …
instead
it’s close to the same thing but not quite
composed
is better for two primary reasons: 1. it means you can create and hold on to the reference of the modifier in a non-composable scope, which is important 2. it means that the composable state that it uses will be 1:1 with the layout nodes that it is modified to. This means that if you apply the modifier to several different layout nodes, it will have independent state for each one
k

karandeep singh

05/03/2020, 6:59 PM
I still can't use the extension function in the existing api. right? we can't really chain the modifiers.
l

Leland Richardson [G]

05/03/2020, 7:30 PM
you should be able to
at least that was the impression I was under
why do you think you can’t?
k

karandeep singh

05/03/2020, 7:33 PM
lamba's are not allowed with composable I think. Getting this error at build time on writing this code.
Functions which invoke @Composable functions must be marked with the @Composable annotation
Copy code
@Composable
fun Modifier.shimmer() = {
    val progress = animatedFloat(0f)
    onActive {
        progress.loop(0f, 1f, 1000)
        onDispose {
            progress.stop()
        }
    }
    remember { ShimmerModifier(progress) }
}
z

Zach Klippenstein (he/him) [MOD]

05/03/2020, 7:53 PM
I don't think you want a lambda at all. Should be
shimmer() {
, not
shimmer() = {
. And then add a
return
before
remember
.
k

karandeep singh

05/03/2020, 7:55 PM
but composable functions cannot return anything. right? @Zach Klippenstein (he/him) [MOD]
z

Zach Klippenstein (he/him) [MOD]

05/03/2020, 7:56 PM
No, they can return like normal functions.
In Leland's snippet, the lambda passed to
composed
is a composable function, and it's returning that modifier. Basically you're just removing one layer of indirection.
k

karandeep singh

05/03/2020, 8:02 PM
composable functions can only return units. this is very much explained in there talks as well
z

Zach Klippenstein (he/him) [MOD]

05/03/2020, 8:10 PM
That code lab must be old, composable functions have been able to return values since the
+
syntax for effects was deprecated, in dev05 or some time around then I think? Look at that source link I posted, the function parameter to
composed
is a composable function that returns a
Modifier
.
k

karandeep singh

05/03/2020, 8:19 PM
but I just tried to run a @composable function with return and it works 🙊
so I was able to run the code given by Leland. Though with remember it gives build error but without it works.
and getting crashes now . 😄
@Zach Klippenstein (he/him) [MOD] Thank you for letting me know that we can return values from compose functions. 🙂
l

Leland Richardson [G]

05/03/2020, 10:34 PM
yes returning values is fine. The codelab you’re referencing is old, but the thinking hasn’t changed all that much. We had this notion of “effects” before which we have now unified with composable functions which return values. When we first announced compose, there were a lot of people that were confused about how a composable function which returned Unit could mean anything, since most comparable frameworks work in a way where you have a function returning some type of tree-like data structure to describe what the component is rendering. Compose works in somewhat of a different way, where the structure of the code that is executing is instead interpreted as the tree. The language you screenshotted above is sort of trying to explain that, but we didn’t realize at the time that we would later have composable functions returning values also :)
and now, in fact, composables which return values are an important subset of our API surface. Things like
remember
and
state
etc are pretty fundamental components to compose overall
k

Kazemihabib1996

05/08/2020, 8:52 PM
@Leland Richardson [G] based on the docs of
Model
class:
Copy code
Composable functions which directly or indirectly read properties of the model class, the composables will be recomposed whenever any properties of the the model are written to.
but
ContentDrawScope.draw()
is not a Composable function, why does it recompose whenever progress is being updated?
l

Leland Richardson [G]

05/08/2020, 8:59 PM
good question. We also set up model observation during draw and layout phases
👍 1
so draw/layout will similarly get invalidated by model changes if they are used inside that scope
👍 1
hope that makes sense
k

Kazemihabib1996

05/08/2020, 9:00 PM
Yeah, thank you.
9 Views