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

Guy Bieber

04/28/2020, 7:05 PM
I am using dev-09 and having an issue on subsequent calls to setContext, particularly from composable functions. Here is the code:
Copy code
setContent {
                        MaterialTheme {
                            //for some reason this gets an error
                            //pageData.page()

                            // moved to a switch statement
                            when (page) {
                                Pages.SPLASH_PAGE -> {
                                    SplashPage()
                                }
                                Pages.LOGIN_PAGE -> {
                                    LoginPage()
                                }
                                Pages.RESET_PASSWORD_PAGE -> {
                                    ForgotPasswordPage()
Here is the error:
Copy code
2020-04-28 11:55:16.113 26150-26150/com.nikolamotor.nikolamotor E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.nikolamotor.nikolamotor, PID: 26150
    java.lang.IllegalArgumentException: Start/end imbalance
        at androidx.compose.Composer.finalizeCompose(Composer.kt:1595)
        at androidx.compose.Composer.endRoot(Composer.kt:509)
        at androidx.compose.Recomposer.recompose(Recomposer.kt:79)
        at androidx.compose.Recomposer.access$recompose$1(Unknown Source:0)
        at androidx.compose.Recomposer$Companion.recompose$compose_runtime_release(Recomposer.kt:56)
        at androidx.compose.CompositionImpl.setContent(Composition.kt:91)
        at androidx.ui.core.WrappedComposition.setContent(Wrapper.kt:221)
        at androidx.ui.core.WrapperKt.doSetContent(Wrapper.kt:201)
        at androidx.ui.core.WrapperKt.setContent(Wrapper.kt:156)
        at androidx.ui.core.WrapperKt.setContent(Wrapper.kt:129)
        at com.nikolamotor.nikolamotor.MainActivity$PageControl.SwitchPage(MainActivity.kt:207)
        at com.nikolamotor.nikolamotor.MainActivity$HomePage$3.invoke(MainActivity.kt:499)
        at com.nikolamotor.nikolamotor.MainActivity$HomePage$3.invoke(Unknown Source:6)
        at androidx.compose.internal.RestartableFunction.invoke(RestartableFunction.kt:140)
        at androidx.compose.internal.RestartableFunction$invoke$1.invoke(RestartableFunction.kt:141)
        at androidx.compose.internal.RestartableFunction$invoke$1.invoke(Unknown Source:3)
        at androidx.compose.RecomposeScope.compose(Composer.kt:265)
        at androidx.compose.Composer.composeScope(Composer.kt:1431)
        at androidx.compose.Composer.recomposeComponentRange(Composer.kt:1377)
        at androidx.compose.Composer.skipCurrentGroup(Composer.kt:1426)
        at androidx.compose.Composer.recompose(Composer.kt:1495)
        at androidx.compose.Recomposer.performRecompose(Recomposer.kt:107)
        at androidx.compose.Recomposer.dispatchRecomposes(Recomposer.kt:135)
        at androidx.compose.AndroidRecomposer.access$dispatchRecomposes$1(Unknown Source:0)
        at androidx.compose.AndroidRecomposer$frameCallback$1.doFrame(AndroidRecomposer.kt:27)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:965)
        at android.view.Choreographer.doCallbacks(Choreographer.java:791)
        at android.view.Choreographer.doFrame(Choreographer.java:722)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Any thoughts? Note I can call the same function from back and it works every time (outside a composable function)
Copy code
//@Composable
    override fun onBackPressed() {
        pg.BackPage()
        //super.onBackPressed()
    }
Copy code
fun BackPage () {
            if (currentPage != <http://Pages.NO|Pages.NO>_PAGE) {
                val pageData = pageMap[currentPage]
                if (pageData != null) {
                    // this page has a specific back page
                    if (pageData.backPage != <http://Pages.NO|Pages.NO>_PAGE) {
                        SwitchPage(pageData.backPage)
                    // this go back to
                    } else if (priorPage != <http://Pages.NO|Pages.NO>_PAGE){
                        SwitchPage(priorPage)
                    }
                }
            }
        }
a

Adam Powell

04/28/2020, 7:22 PM
I would recommend against calling setContent from inside composition. You should only need to call setContent once; changes from there should be driven by data updates.
This can't be made to work for at least two reasons: you're creating a side effect of composition, and that side effect is trying to synchronously recompose the composition you're already in the process of composing. 🙂
g

Guy Bieber

04/28/2020, 7:33 PM
How do I change pages then?
This used to work in dev-05
startActivity looks like the answer from jetpack
The jetpack-compose-playground is really complicated in how it launches different demo pages. I guess I need an activity for every page now?
v

Vinay Gaba

04/28/2020, 8:16 PM
Ignore the syntax in this example as its using an older version of compose, but I was doing something similar to what you were without needing additional
setContent
calls - https://github.com/vinaygaba/Droidcon-SF-2019-Architecture-Agnostic-UI-Development/blob/master/app/src/main/java/com/droidconsf/architectureagnosticuidevelopment/ui/comicbooks/compose/ComicsApp.kt#L21
👍 2
g

Guy Bieber

04/28/2020, 9:59 PM
Thanks. Worked great. I knew there was a more declarative way of handling it.
🙌🏼 1