hi guys, does anybody know if there is an easy way...
# compose
a
hi guys, does anybody know if there is an easy way to do the following:
Copy code
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()) }
j
This looks exceedingly questionable. Maybe you can back up a bit and describe what you're trying to do?
3
a
I am trying to do a multiple back stack navigation
there is a BecomePartnerTab in my app
Copy code
@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
j
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:
Copy code
class AppData {
  var homePageData by mutableStateOf(...)
  var aboutPageData by mutableStateOf(...)
  var detailsPageData by mutableStateOf(...)
}
🤔 1
a
is there a way to iterate through enums?
j
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.
a
Copy code
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
j
Sorry, I still don't see the problem.
a
Copy code
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:
Copy code
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?
j
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.
☝️ 2
a
Alright, that seems reasonable
thanks
I was just wondering if that was possible
j
👍 np, good luck!
a
what about another article
I mean do you know if there is a fresh, google-supported article about it?
j
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
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 more https://twitter.com/ianhlake/status/1377382189654929411
👍 1
🙏 1