Skip to content

Parent interaction is gone once it has a child on top #600

@peposdd

Description

@peposdd

Context about our use case:
Showing Google Maps on the background all the time and show our own UI on top of the map. Transitions between our UI keeps Google Maps on the background the whole time, since destroy/create new maps is very expensive.

  • Using Appyx 1.3.0 we were having a Google Maps root node and our UI nodes being children of it. We were able to interact with our UI and with the Map below without any issue.
  • Using Appyx 2.0.0-alpha05, same configuration makes the Map below non interactive, only the children UI is getting proper interaction.

Attached videos and minimum reproducible code for 1.3.0 and 2.0.0-alpha05:

  • Version Appyx 1.3.0
class MainActivity : ComponentActivity() {

    private lateinit var appyxIntegrationPoint: ActivityIntegrationPoint

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        appyxIntegrationPoint = ActivityIntegrationPoint(
            activity = this,
            savedInstanceState = savedInstanceState
        )
        setContent {
            NodeHost(appyxIntegrationPoint) {
                RootNode(it)
            }
        }
    }
}

class RootNode(
    buildContext: BuildContext,
    private val backStack: BackStack<NavTarget> = BackStack(
        initialElement = NavTarget.Child1,
        savedStateMap = buildContext.savedStateMap
    )
) : ParentNode<RootNode.NavTarget>(
    buildContext = buildContext,
    navModel = backStack
) {

    sealed class NavTarget : Parcelable {
        @Parcelize
        data object Child1 : NavTarget()
    }

    override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node =
        when (navTarget) {
            NavTarget.Child1 -> Child1Node(
                buildContext = buildContext
            )
        }

    @Composable
    override fun View(modifier: Modifier) {

        Box(modifier = modifier.fillMaxSize()) {
            var selected by remember { mutableStateOf(true) }
            Box(
                modifier = modifier
                    .fillMaxSize()
                    .background(
                        if (selected) {
                            Color.Cyan
                        } else {
                            Color.Red
                        }
                    ).clickable {
                        selected = !selected
                    },
                contentAlignment = Alignment.Center,
            ) {
                Text(
                    text = "Google Maps Appyx 1.3.0"
                )
            }
            Children(
                modifier = modifier.fillMaxSize(),
                navModel = backStack,
                transitionHandler = rememberBackstackSlider(transitionSpec = { spring() })
            )
        }
    }
}

class Child1Node(
    buildContext: BuildContext
) : Node(buildContext) {

    @Composable
    override fun View(modifier: Modifier) {
        Box(
            modifier = modifier,
            contentAlignment = Alignment.BottomCenter
        ) {
            Box(modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
                .padding(10.dp)
                .background(Color.Black.copy(alpha = 0.3f))
                .clickable {  }
            )
        }
    }
}
  • Version Appyx 2.0.0
class MainActivity : ComponentActivity() {

    private lateinit var appyxIntegrationPoint: ActivityIntegrationPoint

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        appyxIntegrationPoint = ActivityIntegrationPoint(
            activity = this,
            savedInstanceState = savedInstanceState
        )
        setContent {
            NodeHost(
                lifecycle = AndroidLifecycle(LocalLifecycleOwner.current.lifecycle),
                integrationPoint = appyxIntegrationPoint
            ) {
                RootNode(it)
            }
        }
    }
}

class RootNode(
    nodeContext: NodeContext,
    private val backStack: BackStack<NavTarget> = BackStack(
        model = BackStackModel(
            initialTarget = NavTarget.Child1,
            savedStateMap = nodeContext.savedStateMap,
        ),
        visualisation = { BackStackFader(it) }
    )
) : Node<RootNode.NavTarget>(
    appyxComponent = backStack,
    nodeContext = nodeContext,

) {

    sealed class NavTarget : Parcelable {
        @Parcelize
        data object Child1 : NavTarget()
    }

    override fun buildChildNode(navTarget: NavTarget, nodeContext: NodeContext): Node<*> {
        return when (navTarget) {
            NavTarget.Child1 -> ChildNode1(nodeContext)
        }
    }

    @Composable
    override fun Content(modifier: Modifier) {
        Box(modifier = modifier.fillMaxSize()) {
            var selected by remember { mutableStateOf(true) }
            Box(
                modifier = modifier
                    .fillMaxSize()
                    .background(
                        if (selected) {
                            Color.Cyan
                        } else {
                            Color.Red
                        }
                    )
                    .clickable {
                        selected = !selected
                    },
                contentAlignment = Alignment.Center,
            ) {
                Text(
                    text = "Google Maps Appyx 2.0.0"
                )
            }
            AppyxNavigationContainer(
                appyxComponent = backStack,
                modifier = Modifier
            )
        }
    }
}

class ChildNode1(
    nodeContext: NodeContext
) : LeafNode(nodeContext) {

    @Composable
    override fun Content(modifier: Modifier) {
        Box(
            modifier = modifier.fillMaxSize(),
            contentAlignment = Alignment.BottomCenter
        ) {
            Box(modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
                .padding(10.dp)
                .background(Color.Black.copy(alpha = 0.3f))
                .clickable { }
            )
        }
    }
}

Video:

appyx_200_parent_interaction.mp4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions