Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to pass Scaffold PaddingValues to CurrentTab() #409

Open
harry248 opened this issue May 4, 2024 · 3 comments
Open

Make it possible to pass Scaffold PaddingValues to CurrentTab() #409

harry248 opened this issue May 4, 2024 · 3 comments

Comments

@harry248
Copy link

harry248 commented May 4, 2024

If nesting a Scaffold inside a TabNavigator, the PaddingValues that are passed to the content lambda of the Scaffold can't be passed to CurrentTab(). Would be nice to have some official support.

@hristogochev
Copy link

You can use the following interface and function to be able to pass the PaddingValues:

@Composable
fun CurrentTabX(
    innerPadding: PaddingValues, snackBarHostState: SnackbarHostState
) {
    val tabNavigator = LocalTabNavigator.current
    val currentTab = tabNavigator.current as TabX

    tabNavigator.saveableState("currentTab") {
        currentTab.Content(innerPadding, snackBarHostState)
    }
}


interface TabX : Tab {

    @Composable
    fun Content(
        innerPadding: PaddingValues,
        snackBarHostState: SnackbarHostState,
    )

    @Composable
    override fun Content() {
        error("Called Content without arguments")
    }
}

Simply inherit from TabX instead of Tab for your Tabs and replace CurrentTab() with CurrentTabX()

@hristogochev
Copy link

If you also want to then add a fade transition between the Tabs you could use:

typealias TabTransitionContent = @Composable AnimatedVisibilityScope.(Tab) -> Unit


@Composable
fun TabTransition(
    navigator: TabNavigator,
    transition: AnimatedContentTransitionScope<Tab>.() -> ContentTransform,
    modifier: Modifier = Modifier,
    content: TabTransitionContent
) {
    AnimatedContent(
        targetState = navigator.current,
        transitionSpec = transition,
        modifier = modifier
    ) { tab ->
        navigator.saveableState("transition", tab) {
            content(tab)
        }
    }
}

@Composable
fun FadeTabTransition(
    navigator: TabNavigator,
    modifier: Modifier = Modifier,
    animationSpec: FiniteAnimationSpec<Float> = spring(stiffness = Spring.StiffnessMediumLow),
    content: TabTransitionContent
) {
    TabTransition(
        navigator = navigator,
        modifier = modifier,
        content = content,
        transition = { fadeIn(animationSpec = animationSpec) togetherWith fadeOut(animationSpec = animationSpec) }
    )
}

And then call the following for the content of your Scaffold instead of CurrentTabX:

content = { innerPadding ->
    FadeTabTransition(it) { tab ->
        (tab as TabX).Content(innerPadding, snackBarHostState)
    }
},

@harry248
Copy link
Author

Sorry for the late reply @hristogochev... Looks like a nice solution, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants