Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Youtube like BottomNavigation

Youtube like BottomNavigation

kobito-kaba

July 01, 2022
Tweet

More Decks by kobito-kaba

Other Decks in Technology

Transcript

  1. Hiroyuki Mori
    @moridroid
    BottomNavigationView
    for humankind

    View Slide

  2. ↓This

    View Slide

  3. making a new app

    View Slide

  4. making a new app
    - multi-module project

    View Slide

  5. making a new app
    - multi-module project
    - Jetpack Navigation

    View Slide

  6. making a new app
    - multi-module project
    - Jetpack Navigation
    - BottomNavigationView

    View Slide

  7. making a new app
    - multi-module project
    - Jetpack Navigation
    - BottomNavigationView

    View Slide

  8. making a new app
    - multi-module project
    - Jetpack Navigation
    - BottomNavigationView

    View Slide

  9. No support for
    Multiple Backstack

    View Slide

  10. https://bit.ly/3wXjGLy

    View Slide

  11. Click

    View Slide

  12. View Slide

  13. Click

    View Slide

  14. View Slide

  15. Click
    QUIZ:
    When the Home menu
    is clicked, which
    screen is displayed?
    1. Welcome
    2. About

    View Slide

  16. View Slide

  17. disappear
    go down

    View Slide

  18. No!

    View Slide

  19. Behavior Changed
    support multiple backstack
    from
    Fragment 1.4.0-alpha01
    NavigationUI 2.4.0-alpha01

    View Slide

  20. Just update
    dependencies

    View Slide

  21. This isn’t nice

    View Slide

  22. Click

    View Slide

  23. Click

    View Slide

  24. Click

    View Slide

  25. View Slide

  26. This isn’t nice

    View Slide

  27. This isn’t nice

    View Slide

  28. QUIZ:
    If you click the back
    key, which screen is
    displayed?
    1. Welcome
    2. About
    Click

    View Slide

  29. QUIZ:
    If you click the back
    key, which screen is
    displayed?
    1. Welcome
    2. About
    Click

    View Slide

  30. QUIZ:
    If you click the back
    key, which screen is
    displayed?
    1. Welcome
    2. About
    Click

    View Slide

  31. View Slide

  32. Click

    View Slide

  33. View Slide

  34. How
    Multiple backstack
    works

    View Slide

  35. Backstack  
    SavedState  

    View Slide

  36. Backstack  
    SavedState  
    Click

    View Slide

  37. Backstack  
    SavedState  
    menu A 
    Save
    Backstack  
    SavedState  
    Click

    View Slide

  38. Backstack  
    SavedState  
    menu A 
    Click

    View Slide

  39. Backstack  
    SavedState  
    menu B 
    menu A 
    Restore
    Save
    Click

    View Slide

  40. Backstack  
    SavedState  
    menu A  menu B 
    ← When the back key is pressed
    ← Can’t decide
     which should be restored

    View Slide

  41. Backstack  
    SavedState  
    menu A  menu B 
    ← New Instance
    Backstack  
    SavedState  
    menu A  menu B 

    View Slide

  42. Backstack  
    SavedState  
    menu A  menu B 
    menu A  menu B 
    Click

    View Slide

  43. menu B 
    menu A 
    Backstack  
    SavedState  
    menu B 
    Backstack  
    SavedState  

    View Slide

  44. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  45. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  46. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  47. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  48. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  49. graph
    A1 B1 C1 D1
    B2
    B3
    C2
    C3
    D2 D3
    C4 C5

    View Slide

  50. What
    the ideal
    Bottom Navigation
    should be

    View Slide

  51. View Slide

  52. View Slide

  53. C1

    View Slide

  54. C1 C2

    View Slide

  55. C1 C2 C3

    View Slide

  56. C1 C2 C3
    D1
    Click
    menu D

    View Slide

  57. C1 C2 C3
    D1 D2
    Click
    menu D

    View Slide

  58. C1 C2 C3
    D1 D2
    Click
    menu D
    Click
    menu C

    View Slide

  59. C1 C2 C3
    D1 D2
    Click
    menu D
    Click
    menu C
    Then, the back key will navigate…
    ① ② ③
    ④ ⑤

    C3
    C3 C2
    D2 D1 C3 C2 C1
    C1 D2 D1
    ⑥ ⑤ ④ ③ ② ①

    ③ ① ⑤ ④

    View Slide

  60. How to implement
    Backstack management

    View Slide

  61. https://bit.ly/3zdDxrn

    View Slide

  62. First of all:
    Reorderable Stack

    View Slide

  63. class NavStack @Inject constructor(){
    data class NavRecord(val screenId: Int, val menuId: Int)
    private val selectedMenu = MutableStateFlow(R.id.none)
    fun push(screenId: Int, menuId: Int) { ... }
    fun pop(): NavRecord? { ... }
    fun peekAt(index: Int) : NavRecord? { ... }
    val size: Int get() { … }
    fun findByMenuId(menuId: Int): List { ... }
    fun moveToTop(menuId: Int) { ... }
    fun removeAll(menuId: Int) { ... }
    }

    View Slide

  64. ● Navigate
    ● Switch menu
    ● Go Back

    View Slide

  65. Navigate
    Switch menu
    Go Back
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }

    View Slide

  66. Navigate
    case 1:
    within the same menu
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }

    View Slide

  67. if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    Navigate
    case 2:
    across menus

    View Slide

  68. Navigate
    case 1:
    within the same menu
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }

    View Slide

  69. Navigate
    case 1:
    within the same menu
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }

    View Slide

  70. Navigate
    case 1:
    within the same menu
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    fragmentManager.commit {
    setReorderingAllowed(true)
    replace(requireNotNull(containerId),
    clazz.newInstance().apply { arguments = args })
    addToBackStack(menuId.toString())
    }

    View Slide

  71. Navigate
    case 1:
    within the same menu
    if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    fragmentManager.commit {
    setReorderingAllowed(true)
    replace(requireNotNull(containerId),
    clazz.newInstance().apply { arguments = args })
    addToBackStack(menuId.toString())
    }

    View Slide

  72. if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    Navigate
    case 2:
    across menus

    View Slide

  73. if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    Navigate
    case 2:
    across menus

    View Slide

  74. if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    Navigate
    case 2:
    across menus

    View Slide

  75. if (currentMenuId == nextMenuId) {
    stack.push(screenId, currentMenuId)
    fragmentManager.replace(currentMenuId, nextScreen.clazz, arguments)
    } else {
    stack.moveToTop(nextMenuId)
    stack.push(screenId, nextMenuId)
    fragmentManager.saveBackStack(currentMenuId.toString())
    fragmentManager.restoreBackStack(nextMenuId.toString())
    fragmentManager.replace(nextMenuId, nextScreen.clazz, arguments)
    }
    Navigate
    case 2:
    across menus

    View Slide

  76. Navigate
    Switch menu
    Go Back
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  77. Switch Menu
    case 1:
    re-select menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  78. Switch Menu
    case 2:
    has no records
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  79. Switch Menu
    case 3:
    click the same menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  80. Switch Menu
    case 1:
    re-select menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  81. Switch Menu
    case 1:
    re-select menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  82. Switch Menu
    case 1:
    re-select menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  83. Switch Menu
    case 2:
    has no records
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  84. Switch Menu
    case 2:
    has no records
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  85. Switch Menu
    case 2:
    has no records
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  86. Switch Menu
    case 3:
    click the same menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  87. Switch Menu
    case 3:
    click the same menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  88. Switch Menu
    case 3:
    click the same menu
    when {
    currentMenu.menuId == nextMenu.menuId -> {
    stack.removeAll(currentMenu.menuId)
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.clearBackStack(nextMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    stack.findByMenuId(nextMenu.menuId).isEmpty() -> {
    stack.push(startScreen.screenId, nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.replace(nextMenu.menuId, startScreen.clazz)
    }
    else -> {
    stack.moveToTop(nextMenu.menuId)
    fragmentManager.saveBackStack(currentMenu.menuId.toString())
    fragmentManager.restoreBackStack(nextMenu.menuId.toString())
    }
    }

    View Slide

  89. Navigate
    Switch menu
    Go Back
    when {
    destRecord == null && currentMenuId == graph.startMenuId -> {
    activity.finish()
    }
    destRecord == null -> {
    stack.push(startScreen.screenId, graph.startMenuId)
    fragmentManager.replace(graph.startMenuId, startScreen.clazz)
    }
    destRecord.menuId == currentMenuId -> {
    stack.pop()
    fragmentManager.popBackStack()
    }
    else -> {
    stack.pop()
    fragmentManager.popBackStack()
    fragmentManager.restoreBackStack(destRecord.menuId.toString())
    }
    }

    View Slide

  90. Go Back
    case 1:
    can’t back
    at default menu
    when {
    destRecord == null && currentMenuId == graph.startMenuId -> {
    activity.finish()
    }
    destRecord == null -> {
    stack.push(startScreen.screenId, graph.startMenuId)
    fragmentManager.replace(graph.startMenuId, startScreen.clazz)
    }
    destRecord.menuId == currentMenuId -> {
    stack.pop()
    fragmentManager.popBackStack()
    }
    else -> {
    stack.pop()
    fragmentManager.popBackStack()
    fragmentManager.restoreBackStack(destRecord.menuId.toString())
    }
    }

    View Slide

  91. Go Back
    case 2:
    can’t back
    at not default menu
    when {
    destRecord == null && currentMenuId == graph.startMenuId -> {
    activity.finish()
    }
    destRecord == null -> {
    stack.push(startScreen.screenId, graph.startMenuId)
    fragmentManager.replace(graph.startMenuId, startScreen.clazz)
    }
    destRecord.menuId == currentMenuId -> {
    stack.pop()
    fragmentManager.popBackStack()
    }
    else -> {
    stack.pop()
    fragmentManager.popBackStack()
    fragmentManager.restoreBackStack(destRecord.menuId.toString())
    }
    }

    View Slide

  92. Go Back
    case 3:
    navigate back inside
    the same menu
    when {
    destRecord == null && currentMenuId == graph.startMenuId -> {
    activity.finish()
    }
    destRecord == null -> {
    stack.push(startScreen.screenId, graph.startMenuId)
    fragmentManager.replace(graph.startMenuId, startScreen.clazz)
    }
    destRecord.menuId == currentMenuId -> {
    stack.pop()
    fragmentManager.popBackStack()
    }
    else -> {
    stack.pop()
    fragmentManager.popBackStack()
    fragmentManager.restoreBackStack(destRecord.menuId.toString())
    }
    }

    View Slide

  93. Go Back
    case 4:
    navigate back
    across menus
    when {
    destRecord == null && currentMenuId == graph.startMenuId -> {
    activity.finish()
    }
    destRecord == null -> {
    stack.push(startScreen.screenId, graph.startMenuId)
    fragmentManager.replace(graph.startMenuId, startScreen.clazz)
    }
    destRecord.menuId == currentMenuId -> {
    stack.pop()
    fragmentManager.popBackStack()
    }
    else -> {
    stack.pop()
    fragmentManager.popBackStack()
    fragmentManager.restoreBackStack(destRecord.menuId.toString())
    }
    }

    View Slide

  94. in Summary:
    - Fragment supports Multiple Backstack
    - BottomNavigationView works weirdly
    - You can make it by yourself
    - I don’t want to make it

    View Slide

  95. in Summary:
    - Fragment supports Multiple Backstack
    - BottomNavigationView works weirdly
    - You can make it by yourself
    - I don’t want to make it

    View Slide

  96. in Summary:
    - Fragment supports Multiple Backstack
    - BottomNavigationView works weirdly
    - You can make it by yourself
    - I don’t want to make it

    View Slide

  97. in Summary:
    - Fragment supports Multiple Backstack
    - BottomNavigationView works weirdly
    - You can make it by yourself
    - I don’t want to make it

    View Slide

  98. in Summary:
    - Fragment supports Multiple Backstack
    - BottomNavigationView works weirdly
    - You can make it by yourself
    - I don’t want to make it

    View Slide

  99. Hiroyuki Mori
    @moridroid
    Thank you

    View Slide