Skip to content

Instantly share code, notes, and snippets.

@vahid-m
Created September 17, 2024 11:07

Revisions

  1. vahid-m created this gist Sep 17, 2024.
    86 changes: 86 additions & 0 deletions BottomNavFragment.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    class RootFragment: KeyedFragment(R.layout.root_fragment) {
    private val binding by viewBinding(RootFragmentBinding::bind)

    private lateinit var firstFragment: FirstFragment
    private lateinit var secondFragment: SecondFragment
    private lateinit var thirdFragment: ThirdFragment

    private val fragments: Array<Fragment> get() = arrayOf(firstFragment, secondFragment, thirdFragment)
    private var selectedIndex = 0

    private val tabs: Array<TextView> get() = binding.run {
    arrayOf(buttonFirstTab, buttonSecondTab, buttonThirdTab)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (savedInstanceState == null) {
    val firstFragment = FirstFragment().also { this.firstFragment = it }
    val secondFragment = SecondFragment().also { this.secondFragment = it }
    val thirdFragment = ThirdFragment().also { this.thirdFragment = it }

    childFragmentManager.beginTransaction()
    .add(R.id.containerBottomNavContent, firstFragment, "firstFragment")
    .add(R.id.containerBottomNavContent, secondFragment, "secondFragment")
    .add(R.id.containerBottomNavContent, thirdFragment, "thirdFragment")
    .selectFragment(selectedIndex)
    .commit()
    } else {
    selectedIndex = savedInstanceState.getInt("selectedIndex", 0)

    firstFragment = childFragmentManager.findFragmentByTag("firstFragment") as FirstFragment
    secondFragment = childFragmentManager.findFragmentByTag("secondFragment") as SecondFragment
    thirdFragment = childFragmentManager.findFragmentByTag("thirdFragment") as ThirdFragment
    }
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    tabs.forEachIndexed { index, textView ->
    textView.setOnClickListener {
    selectFragment(index)
    }
    }

    setupTabSelectedState(selectedIndex)
    }

    override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("selectedIndex", selectedIndex)
    }

    private fun FragmentTransaction.selectFragment(selectedIndex: Int): FragmentTransaction {
    fragments.forEachIndexed { index, fragment ->
    if (index == selectedIndex) {
    attach(fragment)
    } else {
    detach(fragment)
    }
    }

    return this
    }

    private fun setupTabSelectedState(selectedIndex: Int) {
    tabs.forEachIndexed { index, textView ->
    textView.setTextColor(when {
    index == selectedIndex -> ContextCompat.getColor(requireContext(), R.color.tab_selected)
    else -> ContextCompat.getColor(requireContext(), R.color.tab_unselected)
    })
    }
    }

    private fun selectFragment(indexToSelect: Int) {
    this.selectedIndex = indexToSelect

    setupTabSelectedState(indexToSelect)

    childFragmentManager.beginTransaction()
    .selectFragment(indexToSelect)
    .commit()
    }
    }