Skip to content

Instantly share code, notes, and snippets.

@BurakDizlek
Created August 26, 2020 15:26
Show Gist options
  • Save BurakDizlek/07c30acc60c66bacdf5bf19fb55ab441 to your computer and use it in GitHub Desktop.
Save BurakDizlek/07c30acc60c66bacdf5bf19fb55ab441 to your computer and use it in GitHub Desktop.
Android Fragment Manager Classes
Add base fragment : backStackManager?.addBaseFragment(showcaseFragment, R.id.home)
Add subFragment : backStackManager?.loadFragmentAndAddToBackStack(fragment = event.fragment)
backStackManager?.loadFragmentAndAddToBackStack(fragment = event.fragment,menuId = event.menuId)
Pop Backstack : backStackManager?.popFragmentBackStack(activeMenuId)
Switch Menu : private fun switchMenu(activeMenuId: Int,targetMenuId: Int) { //Should invoke in navigationViewSelectedListener.
Logger.d(TAG, "Menu Switched -> $activeMenuId -> $targetMenuId")
backStackManager?.handleMenuSwitch(activeMenuId, targetMenuId)
backStackManager?.updateMenuStackCount(targetMenuId)
}
private fun setSelectedNavigationViewItem(itemId: Int) { //Should invoke in navigationViewSelectedListener.
binding.bottomNavigationView.menu.findItem(itemId).isChecked = true
}
class BackStack {
private val TAG = this.javaClass.simpleName
private val homeStack = Stack<Fragment>()
private val categoriesStack = Stack<Fragment>()
private val favoritesStack = Stack<Fragment>()
private val basketStack = Stack<Fragment>()
private val profileStack = Stack<Fragment>()
private val menuStack = Stack<Int>()
fun getMenuStack(): Stack<Int> {
return menuStack
}
val menuStackCount: Int
get() = menuStack.size
fun getFragmentStack(menuId: Int): Stack<Fragment>? {
Logger.d(TAG,"homeStack : ${homeStack.size}")
Logger.d(TAG,"categoriesStack : ${categoriesStack.size}")
Logger.d(TAG,"favoritesStack : ${favoritesStack.size}")
Logger.d(TAG,"basketStack : ${basketStack.size}")
Logger.d(TAG,"profileStack : ${profileStack.size}")
Logger.d(TAG,"menuStack : ${menuStack.size}\n\n")
return when (menuId) {
R.id.home -> homeStack
R.id.categories -> categoriesStack
R.id.favorites -> favoritesStack
R.id.basket -> basketStack
R.id.profile -> profileStack
else -> null
}
}
fun getFragmentStackCount(menuId: Int): Int {
return getFragmentStack(menuId)!!.size
}
fun pushFragmentToStack(menuId: Int, fragment: Fragment) {
if (getFragmentStack(menuId) != null) {
getFragmentStack(menuId)!!.push(fragment)
}
}
fun popFragmentBackStack(menuId: Int, fragmentManager: FragmentManager): Boolean {
if (getFragmentStack(menuId) != null) {
if (getFragmentStack(menuId)!!.size > 1) {
try {
fragmentManager.beginTransaction()
.remove(getFragmentStack(menuId)!!.pop())
.commit()
} catch (e: Exception) {
}
return true
}
}
return false
}
private fun isHaveSameItem(menuId: Int): Boolean {
return menuStack.contains(menuId)
}
fun updateMenuStack(menuId: Int) {
Logger.d(TAG,"updateMenuStack : $menuId")
if (!isHaveSameItem(menuId)) {
menuStack.push(menuId)
}
}
fun popMenuBackStack(): Int {
val stackSize = menuStack.size
Logger.d(TAG,"menuStackSize -> $stackSize")
if (stackSize > 1) {
menuStack.pop()
return menuStack.peek()
}
return menuStack.peek()
}
fun clearBackStackHistories() {
homeStack.clear()
categoriesStack.clear()
favoritesStack.clear()
basketStack.clear()
profileStack.clear()
menuStack.clear()
}
}
class BackStackManager(private val fragmentManager: FragmentManager) {
private val backStack = BackStack()
fun getBackStack(): BackStack {
return backStack
}
val menuStackCount: Int
get() = backStack.menuStackCount
fun loadFragmentAndAddToBackStack(fragment: Fragment, menuId: Int = Config.lastSelectedNavigationItemId, containerId: Int = R.id.fragment_in_main) {
addFragmentAndBackStack(containerId, fragment, menuId)
}
private fun addFragmentAndBackStack(containerId: Int, fragment: Fragment, menuId: Int) {
addFragment(containerId, fragment)
backStack.pushFragmentToStack(menuId, fragment)
}
private fun addFragment(containerId: Int, fragment: Fragment) {
val a = fragmentManager.beginTransaction()
if (containerId == R.id.fragment_in_main) {
a.setCustomAnimations(
android.R.anim.fade_in,
android.R.anim.fade_out,
android.R.anim.fade_in,
android.R.anim.fade_out
)
}
a.add(containerId, fragment)
a.commit()
}
fun addBaseFragment(fragment: Fragment, menuId: Int) {
fragmentManager.beginTransaction()
.add(R.id.fragment_in_main, fragment, fragment.javaClass.simpleName)
.commit()
backStack.pushFragmentToStack(menuId, fragment)
}
fun getFragmentStackCount(menuId: Int): Int {
return backStack.getFragmentStackCount(menuId)
}
fun popFragmentBackStack(menuId: Int): Boolean {
// RxBus.publish(Events.RemoveBackStackListener(menuId))
return backStack.popFragmentBackStack(menuId, fragmentManager)
}
fun updateMenuStackCount(menuId: Int) {
backStack.updateMenuStack(menuId)
}
fun popMenuStack(): Int {
return backStack.popMenuBackStack()
}
fun handleMenuSwitch(activeMenuId: Int, targetMenuId: Int) {
try {
if (activeMenuId != targetMenuId) {
val targetFragments = backStack.getFragmentStack(targetMenuId)
if (targetFragments != null) {
for (fragment in targetFragments) {
fragmentManager.beginTransaction().show(fragment).commit()
}
}
val activeFragments = backStack.getFragmentStack(activeMenuId)
if (activeFragments != null) {
for (fragment in activeFragments) {
fragmentManager.beginTransaction().hide(fragment).commit()
}
}
}
} catch (e: Exception) {
}
}
fun clearBackStackHistory() {
backStack.clearBackStackHistories()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment