Can someone help me with porting this kind of app ...
# compose
p
Can someone help me with porting this kind of app to Compose? I receive my model from a source, for example a json. The model is an array of classes. Those classes represents screens and those screens contains components (image, text, container, etc...). For example, each screen can have an array of components.
Copy code
open class Screen(val id: Int, val components: List<Component>)
open class Component(val id: Int)
class ImageComponent(id: Int, val imageSrc: String) : Component(id)
class TextComponent(id: Int, val text: String) : Component(id)
Now imagine a Screen that contains two texts and one image:
Copy code
Screen(1, listOf(
    TextComponent(1, "hello"),
    TextComponent(2, "World"),
    ImageComponent(3, "hello_world_image_route")
))
Previously on java I had a generateView() method on each screen and component, and those methods where overrided on subclasses and I simply needed to call generateView to get the views for each screen and set them to the content of the current activity. Now I'm trying to migrate this to Compose and MVVM. Now each view must be a Composable, but for obvious reasons, Composables can only be called from other composables and I need to separate the model from the composables in the process to move to MVVM. So I can't have a @Composable method on those classes. Once I have my Screen object, how can I generate composables from it? I can't put a "generateComposable" method on it. I know how to write a @Composable function that paints a Text or an Image, but I don't know where should I put the code to generate that composable for each kind of screen or element when I have the model in memory. Which strategy can I follow?
I tryed adding a
Copy code
@Composable
open fun Composable(modifier: Modifier) {}
on the classes of the model, and each class of the model overrides this to call the correct Composable function which is stored on the UI layer, for example, for Text:
Copy code
@Composable
override fun Composable(modifier: Modifier) {
    TextComposable(
        component = this,
        modifier = modifier
    )
}
Proably this is not the best approach, I'm trying to understand which strategy is better. Any help please?
r
well, based on a component as type (most probably enum) you can generate content on screen so
Copy code
when(type){
type is TextType -> TextComposable(type.data)
type is ImageType -> ImageComposable(type.data)
}
also instead of making everything open you can just make it sealed class something like UiComponent idk you can just iterate through given from BE components and based on type generate a composable
c
@Pablo your approach defies the hole purpose of declarative UI where states define your UI. You should rethink of how to map the Json definition to “states” and get rid of the imperative UI thinking you had with the previous approach.
p
Hi christian yes, I'm trying to do it. But that approach is the best I can imagine for now. I know it's not correct, so I posted here to search for help. Maybe can you help me giving me some samples of how to do it?
On the other hand, mapping the json to states is not possible, because that json is not a state, it defines the structure of an app, I mean, the model, not the state of it.
It can be mapped just to what it is, the structure of the App, the model of it. For example, that structure can be an app with 2 screens, one with a text, and other with a image. That Image can have an associated event, that can be "open browser with X link"
all that is defined in the json
now I need to transform that into a MVVM compose app, and can't figure out how to do it correctly
c
yeah, that is not possible with compose - actually not in a feasible way. your json is imperative so you should stay with the “view” approach.
r
still you have screens with components list model where component should be some sealed type or enum like where components can be mapped to compose function which will generate the view, i might not understand where the problem is
but doing "dynamic" BE driven UI shouldnt be an issue
c
> but doing “dynamic” BE driven UI shouldnt be an issue sure, its possible it, you just need the data in a way you can “react” on it.
p
what is BE ?
r
Backend
p
bytheway, why is not possible christian? why you say that the json is imperative? i don't understand why it's imperative
that json is just a description of the app
{section{tex,image}, section{text]}
c
yes, and Compose does not “describe” the app, it react to states and draws UI
Your json is more waht you have in the view world defined in the XML. a more or less “static” description of the UI.
p
in the same way you paint in a blank paper your app prototypes before you write them in compose, I think you can have the description of the app in a json and then in some way paint the app with compose
c
yes, if that resamples state. Take a Button for instance, a click on it changes some state to show a new “view”. how would you “describe” this in your json.
r
there you have to have some defined actions based on what you receive and this should be set up during view building
if this worked before this can be converted to compose, thats it
p
Copy code
{
    "section1": {
        "title": "example glossary",
		"components": {
            "text": "S",
			"image": {
                "source": "imagesource"
                "action": "open_section_2"
                }
            }
        }
    }
}
if you mean how the actions are mapped in the json, is something like that
action is also a class, is a definition of what to do
c
Seems like @Robert C has a better understanding if Compose then I do. I’ll leave you 2 with further conversations 🙂 😅
😂 1
p
well christian i hope you can stay, i know you from other questions, and i learned a lot from you previously
can't you imagine a way to migrate from that model to a MVVM compose structure?
r
well this is not about compose tbh but about well defined model
c
Maybe this helps to understand the differnce in the 2 approaches and why a JSON description of an UI will not be easily mapped to a Compose App, https://developer.android.com/develop/ui/compose/mental-model
s
If you theoretically had no interaction in the app, but you were only presenting things on the screen, shouldn't it actually be the optimal case of what Compose is good at? You map the json to a model which can describe how the UI will be shown, and in the compose code you go over than model and render the things accordingly, just as Robert describes here https://kotlinlang.slack.com/archives/CJLTWPH7S/p1722513118947649?thread_ts=1722511339.058599&amp;cid=CJLTWPH7S Now of course when interaction comes into play, it goes from trivial to a quite complex problem, but that shouldn't take away from the fact that compose is in fact a great way to "describe" your app. It does react to state and draws UI, that is indeed true, but this state could very well be a static one being derived from a json string I'd say.
p
I like the Robert Cudak approach
what do you think? it's a good approach for you Stylianos?
using that structure is not necessary to have a composable function on each class of the model
so the layers are not merged
m
@Pablo Compose works great for this, here are parts of my model and Compose implementation.