forked from melod1n/fast-messenger
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