Status Update
Comments
le...@google.com <le...@google.com>
mm...@commonsware.com <mm...@commonsware.com> #2
Part of what is needed is the details of the rules that cause a reflection-invoked composable to actually update the UI.
The attached project uses ModalDrawerLayout()
to offer three buttons, driving three different pieces of text to show in the main content area. There are seven different strategies for how we invoke the composable for the main content area, including six reflection options. All work correctly for the default piece of content — that content correctly renders on the screen. Some work correctly when the user clicks an option in the drawer to switch to another piece of content. Some do not — even though we call the composable, the UI does not change.
The seven strategies are:
-
LambdaExample
, which calls a single one-parameter composable via a unique lambda expression (works) -
ReflectionExample
, which calls a single one-parameter composable via reflection, passing in a distinct parameter value for each of the three different pieces of content (works) -
ReflectionFlexExample
, which calls three distinct zero-parameter composables via reflection (does not work) -
ReflectionFixedExample
, which calls three distinct one-parameter composables via reflection, passing in the same value for that parameter each time (does not work) -
ReflectionRandomExample
, which calls three distinct one-parameter composables via reflection, passing in a random value for that parameter each time (works unless you get a really lousy random number draw and wind up with a duplicate) -
ReflectionFlexPreviewExample
, which is the same asReflectionFlexExample
, except instead of my own reflection code, I use a copy of what is inPreviewUtils.kt
fromui-tooling
(does not work) -
ReflectionFixedPreviewExample
, which is the same asReflectionFixedExample
, except instead of my own reflection code, I use a copy of what is inPreviewUtils.kt
fromui-tooling
(does not work)
In the four cases that do not work, even though the composables being called generate different content, that content gets ignored, apparently because the parameter list is the same. The tweak that makes them work is to have a different parameter list, even if the parameters themselves are unused.
Description
A few things in life are guaranteed:
Because of Compose's plugin-supplied compilation magic, reflection gets tricky to do correctly. Compose's injected parameters need values, and while some are straight-forward to obtain (e.g.,
currentComposer
), others are not. Hard-coding injectedInt
parameters to0
might work for now, but it seems like a prescription for long-term maintenance disaster.Ideally, there would be some supported means of invoking composable functions via reflection, even if that support comes with a list of caveats (e.g., performance limitations) and restrictions.
It appears that something along these lines exists already , perhaps for supporting
@Preview
. Exposing thatinvokeComposableMethod()
function or an equivalent would seem like it would help.Thanks for considering this!