Thread
#compose
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    hi guys, does anybody know if there is an easy way to do the following:
    var var1 = rememberSaveable { mutableStateOf(Bundle()) }
    var var2 = rememberSaveable { mutableStateOf(Bundle()) }
    var var3 = rememberSaveable { mutableStateOf(Bundle()) }
    var var4 = rememberSaveable { mutableStateOf(Bundle()) }
    var var5 = rememberSaveable { mutableStateOf(Bundle()) }
    var var6 = rememberSaveable { mutableStateOf(Bundle()) }
    jim

    jim

    1 year ago
    This looks exceedingly questionable. Maybe you can back up a bit and describe what you're trying to do?
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    I am trying to do a multiple back stack navigation
    there is a BecomePartnerTab in my app
    @Composable
    fun BecomePartnerNavigator(
        navState: MutableState<Bundle>,
        hideNavBar: (Boolean) -> Unit,
        startDestination: String = BecomePartnerTab.BecomePartnerRequests.route,
    ) {
        val navController = rememberNavController()
    
        DisposableEffect(true) {
            val callback = NavController.OnDestinationChangedListener { controller, _, arguments ->
                hideNavBar(arguments?.getString(KEY_ROUTE) != startDestination)
                navState.value = controller.saveState() ?: Bundle()
            }
            navController.addOnDestinationChangedListener(callback)
            navController.restoreState(navState.value)
    
            onDispose {
                navController.removeOnDestinationChangedListener(callback)
                // workaround for issue where back press is intercepted
                // outside this tab, even after this Composable is disposed
                navController.enableOnBackPressed(false)
            }
        }
    
        NavHost(
            navController = navController,
            startDestination = startDestination,
        ) {
            BecomePartnerTab.BecomePartnerRequests.content(this, navController)
            BecomePartnerTab.BecomePartnerRequest.content(this, navController)
        }
    
    }
    so, in the mainactivity I have to call
    val becomePartnerNavState = rememberSavedInstanceState(saver = NavStateSaver()) { mutableStateOf(Bundle()) }
    for each tab I have in my app
    and then a when statement to draw correct the tab
    jim

    jim

    1 year ago
    That article is not official guidance written by a Googler, and I think the code there could probably be cleaned up a bit before using it as an example of idiomatic Compose code. Looking at that article, I think I can see what you're trying to achieve. When writing code of that form, I'd recommend putting the data for all your screens into a single object, broken down by screens.
    Something of the form:
    class AppData {
      var homePageData by mutableStateOf(...)
      var aboutPageData by mutableStateOf(...)
      var detailsPageData by mutableStateOf(...)
    }
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    is there a way to iterate through enums?
    jim

    jim

    1 year ago
    I don't know what you mean by "iterate through enums". The code in the article had a giant switch statement for which page is focused, which seems reasonable.
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    enum class BottomNavTab(
        @StringRes val title: Int,
        val icon: @Composable () -> ImageVector,
        val content: @Composable (
            navState: MutableState<Bundle>,
            hideNavBar: (Boolean) -> Unit
        ) -> Unit,
    ) {
    
        HOME(
            R.string.home,
            { Icons.Outlined.Home },
            { navState, hideNavBar -> HomeScreen() }),
        EXPLORE(
            R.string.explore,
            { Icons.Outlined.Explore },
            { navState, hideNavBar -> ExploreScreen() }),
        SEARCH(
            R.string.search,
            { Icons.Outlined.Search },
            { navState, hideNavBar -> SearchNavigator(hideNavBar) }),
        PROFILE(
            R.string.profile,
            { Icons.Outlined.Person },
            { navState, hideNavBar -> ProfileNavigator(hideNavBar) }
        ),
        BECOME_PARTNER(
            R.string.become_partner,
            { Icons.Outlined.List },
            { navState, hideNavBar -> BecomePartnerNavigator(navState, hideNavBar) }
        );
    
    
        companion object {
            fun studentTabs() = arrayOf(EXPLORE, SEARCH, PROFILE)
            fun parentTabs() = arrayOf(EXPLORE, SEARCH, PROFILE)
            fun employeeTabs() = arrayOf(EXPLORE, SEARCH, PROFILE)
            fun teacherTabs() = arrayOf(EXPLORE, SEARCH, PROFILE)
            fun adminTabs() = arrayOf(EXPLORE, SEARCH, PROFILE)
            fun managerTabs() = arrayOf(HOME, BECOME_PARTNER, PROFILE)
            fun unknownTabs() = arrayOf(PROFILE)
    
        }
    
    }
    so I have this enum class
    which changes tabs dynamically depending on who is using the app
    now, in the main activity I need to pass the nav state
    jim

    jim

    1 year ago
    Sorry, I still don't see the problem.
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    val tabs = BottomNavTab.getTabs(role)
    var tabIndex by rememberSaveable { mutableStateOf(0) }
    ...
    tabs[tabIndex].content(navStates[tabIndex], hideNavBar)
    in the last code snippet you can see the navStates statement
    it should be unique to each tab
    they should be remembered, mutable
    and I want them to be in a list
    I tried doing:
    val navStates = rememberSaveable {
        mutableStateListOf(*tabs.map { Bundle() }.toTypedArray())
    }
    but it returns mutableStateList of regular items
    I need list of <mutableStateOf item>
    Or else could you maybe point me to another article about complex bottom navigation that’s officially supported by google?
    jim

    jim

    1 year ago
    Why?
    List<MutableState<Item>>
    is usually not the right thing. But aside from that, I still think you would be better served to have your state be a
    AppData
    . It's fine if some of the users never use some of the fields on your AppData. For instance, if only a manager would ever use the
    BecomePartnerData
    , etc. That field will just be empty for all other users.
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    Alright, that seems reasonable
    thanks
    I was just wondering if that was possible
    jim

    jim

    1 year ago
    👍 np, good luck!
    Altynbek Nurtaza

    Altynbek Nurtaza

    1 year ago
    what about another article
    I mean do you know if there is a fresh, google-supported article about it?
    jim

    jim

    1 year ago
    The primary official documentation we have at the moment is: https://developer.android.com/jetpack/compose/state
    We will likely release more Compose docs when Compose goes to 1.0; I don't remember exactly what all is in those docs though.
    i

    Ian Lake

    1 year ago
    Note that multiple back stacks for Navigation (including Navigation Compose) is under active development (and will be ~2 lines of code compared to the single back stack version of Navigation Compose you can use right now), so you might consider just waiting a bit morehttps://twitter.com/ianhlake/status/1377382189654929411