delete setupWithNavController.kt
This commit is contained in:
@@ -1,251 +0,0 @@
|
|||||||
package com.meloda.fast.base
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.util.SparseArray
|
|
||||||
import androidx.core.util.forEach
|
|
||||||
import androidx.core.util.set
|
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
import com.meloda.fast.R
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
fun BottomNavigationView.setupWithNavController(
|
|
||||||
navGraphIds: List<Int>,
|
|
||||||
fragmentManager: FragmentManager,
|
|
||||||
dataManager: DataManager,
|
|
||||||
containerId: Int,
|
|
||||||
intent: Intent
|
|
||||||
): LiveData<NavController> {
|
|
||||||
|
|
||||||
// Map of tags
|
|
||||||
val graphIdToTagMap = SparseArray<String>()
|
|
||||||
// Result. Mutable live data with the selected controlled
|
|
||||||
val selectedNavController = MutableLiveData<NavController>()
|
|
||||||
|
|
||||||
var firstFragmentGraphId = 0
|
|
||||||
|
|
||||||
// First create a NavHostFragment for each NavGraph ID
|
|
||||||
navGraphIds.forEachIndexed { index, navGraphId ->
|
|
||||||
val fragmentTag = getFragmentTag(index)
|
|
||||||
|
|
||||||
// Find or create the Navigation host fragment
|
|
||||||
val navHostFragment = obtainNavHostFragment(
|
|
||||||
fragmentManager,
|
|
||||||
fragmentTag,
|
|
||||||
navGraphId,
|
|
||||||
containerId
|
|
||||||
)
|
|
||||||
|
|
||||||
// Obtain its id
|
|
||||||
val graphId = navHostFragment.navController.graph.id
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
firstFragmentGraphId = graphId
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save to the map
|
|
||||||
graphIdToTagMap[graphId] = fragmentTag
|
|
||||||
|
|
||||||
// Attach or detach nav host fragment depending on whether it's the selected item.
|
|
||||||
if (this.selectedItemId == graphId) {
|
|
||||||
// Update livedata with the selected graph
|
|
||||||
selectedNavController.value = navHostFragment.navController
|
|
||||||
attachNavHostFragment(fragmentManager, navHostFragment, index == 0)
|
|
||||||
} else {
|
|
||||||
detachNavHostFragment(fragmentManager, navHostFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now connect selecting an item with swapping Fragments
|
|
||||||
var selectedItemTag = graphIdToTagMap[this.selectedItemId]
|
|
||||||
val firstFragmentTag = graphIdToTagMap[firstFragmentGraphId]
|
|
||||||
var isOnFirstFragment = selectedItemTag == firstFragmentTag
|
|
||||||
|
|
||||||
// When a navigation item is selected
|
|
||||||
setOnNavigationItemSelectedListener { item ->
|
|
||||||
// Don't do anything if the state is state has already been saved.
|
|
||||||
if (fragmentManager.isStateSaved) {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
val navController = (fragmentManager.findFragmentByTag(selectedItemTag) as NavHostFragment).navController
|
|
||||||
navController.popBackStack(navController.graph.startDestination, false)
|
|
||||||
if (selectedItemTag != graphIdToTagMap[item.itemId]) {
|
|
||||||
val listCheck = listOf(R.id.contacts, R.id.chats)
|
|
||||||
val newlySelectedItemTag = if (listCheck.contains(item.itemId) && dataManager.token.isBlank()) graphIdToTagMap[R.id.signIn] else graphIdToTagMap[item.itemId]
|
|
||||||
|
|
||||||
// Pop everything above the first fragment (the "fixed start destination")
|
|
||||||
fragmentManager.popBackStack(
|
|
||||||
firstFragmentTag,
|
|
||||||
FragmentManager.POP_BACK_STACK_INCLUSIVE
|
|
||||||
)
|
|
||||||
val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag) as NavHostFragment
|
|
||||||
|
|
||||||
// Exclude the first fragment tag because it's always in the back stack.
|
|
||||||
if (firstFragmentTag != newlySelectedItemTag) {
|
|
||||||
// Commit a transaction that cleans the back stack and adds the first fragment
|
|
||||||
// to it, creating the fixed started destination.
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.setCustomAnimations(
|
|
||||||
R.anim.nav_default_enter_anim,
|
|
||||||
R.anim.nav_default_exit_anim,
|
|
||||||
R.anim.nav_default_pop_enter_anim,
|
|
||||||
R.anim.nav_default_pop_exit_anim
|
|
||||||
)
|
|
||||||
.attach(selectedFragment)
|
|
||||||
.setPrimaryNavigationFragment(selectedFragment)
|
|
||||||
.apply {
|
|
||||||
// Detach all other Fragments
|
|
||||||
graphIdToTagMap.forEach { _, fragmentTagIter ->
|
|
||||||
if (fragmentTagIter != newlySelectedItemTag) {
|
|
||||||
detach(fragmentManager.findFragmentByTag(firstFragmentTag)!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.addToBackStack(firstFragmentTag)
|
|
||||||
.setReorderingAllowed(true)
|
|
||||||
.commit()
|
|
||||||
}
|
|
||||||
selectedItemTag = newlySelectedItemTag
|
|
||||||
isOnFirstFragment = selectedItemTag == firstFragmentTag
|
|
||||||
selectedNavController.value = selectedFragment.navController
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setOnNavigationItemReselectedListener { item ->
|
|
||||||
val newlySelectedItemTag = graphIdToTagMap[item.itemId]
|
|
||||||
val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag) as NavHostFragment
|
|
||||||
val navController = selectedFragment.navController
|
|
||||||
// Pop the back stack to the start destination of the current navController graph
|
|
||||||
if (selectedItemTag != graphIdToTagMap[item.itemId] && dataManager.token.isNotBlank()) {
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.setCustomAnimations(
|
|
||||||
R.anim.nav_default_enter_anim,
|
|
||||||
R.anim.nav_default_exit_anim,
|
|
||||||
R.anim.nav_default_pop_enter_anim,
|
|
||||||
R.anim.nav_default_pop_exit_anim
|
|
||||||
)
|
|
||||||
.attach(selectedFragment)
|
|
||||||
.setPrimaryNavigationFragment(selectedFragment)
|
|
||||||
.apply {
|
|
||||||
// Detach all other Fragments
|
|
||||||
graphIdToTagMap.forEach { _, fragmentTagIter ->
|
|
||||||
if (fragmentTagIter != newlySelectedItemTag) {
|
|
||||||
detach(fragmentManager.findFragmentByTag(firstFragmentTag)!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.addToBackStack(firstFragmentTag)
|
|
||||||
.setReorderingAllowed(true)
|
|
||||||
.commit()
|
|
||||||
selectedItemTag = newlySelectedItemTag
|
|
||||||
isOnFirstFragment = selectedItemTag == firstFragmentTag
|
|
||||||
selectedNavController.value = selectedFragment.navController
|
|
||||||
} else navController.popBackStack(navController.graph.startDestination, false)
|
|
||||||
}
|
|
||||||
// Optional: on item reselected, pop back stack to the destination of the graph
|
|
||||||
setupDeepLinks(navGraphIds, fragmentManager, containerId, intent)
|
|
||||||
|
|
||||||
// Finally, ensure that we update our BottomNavigationView when the back stack changes
|
|
||||||
fragmentManager.addOnBackStackChangedListener {
|
|
||||||
if (!isOnFirstFragment && !fragmentManager.isOnBackStack(firstFragmentTag)) {
|
|
||||||
this.selectedItemId = firstFragmentGraphId
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the graph if the currentDestination is not valid (happens when the back
|
|
||||||
// stack is popped after using the back button).
|
|
||||||
selectedNavController.value?.let { controller ->
|
|
||||||
if (controller.currentDestination == null) {
|
|
||||||
controller.navigate(controller.graph.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectedNavController
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun BottomNavigationView.setupDeepLinks(
|
|
||||||
navGraphIds: List<Int>,
|
|
||||||
fragmentManager: FragmentManager,
|
|
||||||
containerId: Int,
|
|
||||||
intent: Intent
|
|
||||||
) {
|
|
||||||
navGraphIds.forEachIndexed { index, navGraphId ->
|
|
||||||
val fragmentTag = getFragmentTag(index)
|
|
||||||
|
|
||||||
// Find or create the Navigation host fragment
|
|
||||||
val navHostFragment = obtainNavHostFragment(
|
|
||||||
fragmentManager,
|
|
||||||
fragmentTag,
|
|
||||||
navGraphId,
|
|
||||||
containerId
|
|
||||||
)
|
|
||||||
// Handle Intent
|
|
||||||
if (navHostFragment.navController.handleDeepLink(intent) &&
|
|
||||||
selectedItemId != navHostFragment.navController.graph.id
|
|
||||||
) {
|
|
||||||
this.selectedItemId = navHostFragment.navController.graph.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun detachNavHostFragment(
|
|
||||||
fragmentManager: FragmentManager,
|
|
||||||
navHostFragment: NavHostFragment
|
|
||||||
) {
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.detach(navHostFragment)
|
|
||||||
.commitNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun attachNavHostFragment(
|
|
||||||
fragmentManager: FragmentManager,
|
|
||||||
navHostFragment: NavHostFragment,
|
|
||||||
isPrimaryNavFragment: Boolean
|
|
||||||
) {
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.attach(navHostFragment)
|
|
||||||
.apply {
|
|
||||||
if (isPrimaryNavFragment) {
|
|
||||||
setPrimaryNavigationFragment(navHostFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.commitNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun obtainNavHostFragment(
|
|
||||||
fragmentManager: FragmentManager,
|
|
||||||
fragmentTag: String,
|
|
||||||
navGraphId: Int,
|
|
||||||
containerId: Int,
|
|
||||||
): NavHostFragment {
|
|
||||||
// If the Nav Host fragment exists, return it
|
|
||||||
val existingFragment = fragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment?
|
|
||||||
existingFragment?.let { return it }
|
|
||||||
|
|
||||||
// Otherwise, create it and return it.
|
|
||||||
val navHostFragment = NavHostFragment.create(navGraphId)
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.add(containerId, navHostFragment, fragmentTag)
|
|
||||||
.commitNow()
|
|
||||||
return navHostFragment
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FragmentManager.isOnBackStack(backStackName: String): Boolean {
|
|
||||||
val backStackCount = backStackEntryCount
|
|
||||||
for (index in 0 until backStackCount) {
|
|
||||||
if (getBackStackEntryAt(index).name == backStackName) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getFragmentTag(index: Int) = "bottomNavigation#$index"
|
|
||||||
*/
|
|
||||||
Reference in New Issue
Block a user