arkivanov / Decompose

Kotlin Multiplatform lifecycle-aware business logic components (aka BLoCs) with routing (navigation) and pluggable UI (Jetpack Compose, SwiftUI, JS React, etc.)
https://arkivanov.github.io/Decompose
Apache License 2.0
2.24k stars 84 forks source link

ChildPages is not working property #791

Closed 658jjh closed 1 month ago

658jjh commented 1 month ago

It is on the 3.2.0-beta02, I am unsure if it is a known issue. When we use manual swipe with ChildPages, the child = current +/- 2 (up) is not showing the content. Use with navigation.select(index) it work fine

ChildPages(
  pages = component.pages,
  onPageSelected = { index ->
    selectedTabIndex = index
  // If we use navigation.select(index) it also work
  },
  modifier = Modifier.fillMaxWidth().weight(1f)
) { _, page ->
  Screen(page)
}

    val pages: Value<ChildPages<A, Component>> =
      childPages(
        source = navigation,
        serializer = A.serializer(),
        initialPages = {
          Pages(
            items = items,
            selectedIndex = 0
          )
        },
        childFactory = ::createChilds,
    )
arkivanov commented 1 month ago

I couldn't reproduce the issue with the following code. It would be nice if you could provide a complete reproducer with a description of steps to reproduce the issue.

Keep in mind that using navigation.select(index) is required, as shown in the exmaple in the docs.

package com.arkivanov.sample.app

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.pages.ChildPages
import com.arkivanov.decompose.router.pages.ChildPages
import com.arkivanov.decompose.router.pages.Pages
import com.arkivanov.decompose.router.pages.PagesNavigation
import com.arkivanov.decompose.router.pages.childPages
import com.arkivanov.decompose.router.pages.select
import com.arkivanov.decompose.value.Value
import kotlinx.serialization.Serializable

class PagesComponent(componentContext: ComponentContext) : ComponentContext by componentContext {
    private val navigation = PagesNavigation<Config>()

    val pages: Value<ChildPages<Config, PageComponent>> =
        childPages(
            source = navigation,
            serializer = Config.serializer(),
            initialPages = {
                Pages(
                    items = List(10) { Config(it) },
                    selectedIndex = 0
                )
            },
            childFactory = { ctx, _ -> PageComponent(index = ctx.index) },
        )

    fun selectPage(index: Int) {
        navigation.select(index)
    }

    @Serializable
    data class Config(val index: Int)
}

class PageComponent(val index: Int)

@Composable
fun PagesContent(component: PagesComponent) {
    ChildPages(
        pages = component.pages,
        onPageSelected = { index ->
            component.selectPage(index)
            // If we use navigation.select(index) it also work
        },
        modifier = Modifier.fillMaxSize(),
    ) { _, page ->
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
            Text(text = page.index.toString())
        }
    }
}
658jjh commented 1 month ago

oh so we need to use navigation.select(index), I thought onPageSelected just is the callback for page selected index. Thanks