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

Mark

10/15/2023, 5:32 AM
This question is about how to design a state class for a
FlowRow
. Each item contains two
Text
composables where one uses one
FontFamily
and the other uses some other
FontFamily
. These are consistent across items (but with a few exceptions). So should the two font families be declared at the top level of the state class, or at the item level? Declaring at the item level would minimise UI logic but increase redundancy and theoretical inconsistencies. There are also things like fontSize (different for each
Text
within an item) which again should be consistent across items.
e

efemoney

10/15/2023, 9:40 AM
I think a code snippet would be helpful here
a

ascii

10/15/2023, 12:11 PM
Yes, a snippet would help here. From what I understand right now, it seems you're combining data (stuff Text will show) and UI together into the same state? That's always a bad idea. Font info is supplementary and shouldn't be part of the state itself (imo). You can provide what you want either as composition locals or as default args to the item composable, or both, to handle your exceptional cases.
m

Mark

10/15/2023, 12:19 PM
The font must come from the view model (since it’s configurable), so I don’t see how it cannot be part of the UI state. Or am I missing something?
I’m not particularly familiar with using custom
CompositionLocal
and using it with a custom theme, but I guess I could try this to provide the various fonts and font sizes: https://www.kodeco.com/34513206-compositionlocal-in-jetpack-compose?page=3
a

ascii

10/15/2023, 12:54 PM
Ideologically, fonts are part of the theme, and should remain there itself. Putting them into a UI state is certainly not a bad idea, but at best it's just an unnecessary abstraction over an already existing one. At a bare minimum UIs require data (to show) and styles (to make it pretty). These are separate things, and I like to keep them as such. Configurable => user can pick and choose which font(s) they want, maybe in a settings screen, yes? Without any code to go off of, I'm assuming these fonts may be used throughout the app, and not just in this specific
FlowRow
. Perhaps 1 Text is something similar to a title, and the other would be subtitle/body? Your typography can define these styles in a high level app theme composable, all while still respecting user's choices. Code or diagrams would help us realize exactly what you want.
m

Mark

10/15/2023, 3:11 PM
That all makes sense thanks. I can’t easily provide sample code, because the actual code is too detailed and it would take significant time to create a sample, and I’m not sure that’s worth it. I agree it makes sense to store styling (and yes these are needed in other places) in these CompositionLocals and access them directly (rather than passing them in). So as I understand it I should declare a custom theme which initialises these custom CompositionLocals and they would automatically update if they are hooked up to, for example, DataStore flows (where things like user custom font filename are stored)?
This must be a common approach no? A custom theme backed by a datastore that stores user styling preferences? Perhaps something like this: https://levelup.gitconnected.com/theme-management-with-datastore-in-jetpack-compose-c10c043ab276
v

vide

10/16/2023, 10:20 AM
Have you looked at how
MaterialTheme
is implemented?
You can just supply it your own values to use, or if it's not flexible enough, you can roll your own theme composition local
m

Mark

10/16/2023, 11:08 AM
I haven’t looked yet. So would the custom theme collect flows from the data store and so that would be how the changes are propagated?