DEV Community

Devika Android
Devika Android

Posted on

📱 Android Bottom Navigation Style Fragment Switching (Without Navigation Component)

✅ Advantages of This Approach
✔️ Single Activity Architecture
✔️ No Fragment Recreation
✔️ Fast UI Switching
✔️ Back Press Controlled
✔️ Clean & Scalable Code

class MainActivity : AppCompatActivity(), OnClickHandler {
   private lateinit var binding: ActivityMainBinding
   private lateinit var homeFragment: HomeFragment
   private lateinit var secondFragment: SecondFragment
   private lateinit var thirdFragment: ThirdFragment
   private lateinit var activeFragment: Fragment


   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       enableEdgeToEdge()
       binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
       ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
           val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
           v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
           insets
       }

       initView()
   }

   private fun initView() {
       binding.clickHandler = this

       homeFragment = HomeFragment()
       secondFragment = SecondFragment()
       thirdFragment = ThirdFragment()

       supportFragmentManager.beginTransaction().add(binding.llMainView.id, secondFragment)
           .hide(secondFragment)
           .add(binding.llMainView.id, thirdFragment).hide(thirdFragment)
           .add(binding.llMainView.id, homeFragment).commit()

       activeFragment = homeFragment
       handleBackPress()
   }

   private fun switchFragments(target: Fragment) {
       if (activeFragment == target) return
       supportFragmentManager.beginTransaction().hide(activeFragment).show(target).commit()
       activeFragment = target
   }

   private fun handleBackPress() {
       onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
           override fun handleOnBackPressed() {
               if (activeFragment !is HomeFragment) {
                   switchFragments(homeFragment)
               } else {
                   finish()
               }
           }

       })
   }

   override fun view(view: View) {
       when (view.id) {
           binding.llHome.id -> {
               switchFragments(homeFragment)
           }

           binding.llApiCalling.id -> {
               switchFragments(secondFragment)
           }

           binding.llDatabase.id -> {
               switchFragments(thirdFragment)
           }
       }
   }
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools">

   <data>

       <variable
           name="clickHandler"
           type="com.example.androidbox.interfaces.OnClickHandler" />

   </data>

   <androidx.constraintlayout.widget.ConstraintLayout
       android:id="@+id/main"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       tools:context=".ui.activities.MainActivity">

       <LinearLayout
           android:id="@+id/ll_main_view"
           android:layout_width="match_parent"
           android:layout_height="0dp"
           android:orientation="vertical"
           app:layout_constraintBottom_toTopOf="@+id/ll_bottom_sheet"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent">

       </LinearLayout>

       <LinearLayout
           android:id="@+id/ll_bottom_sheet"
           android:layout_width="match_parent"
           android:layout_height="@dimen/_40sdp"
           android:gravity="center"
           android:orientation="horizontal"
           android:weightSum="3"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toBottomOf="@+id/ll_main_view">

           <LinearLayout
               android:id="@+id/ll_home"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="@{(v) -> clickHandler.view(v)}"
               android:orientation="vertical">

               <TextView
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:gravity="center"
                   android:text="Home"
                   android:textColor="@color/black"
                   android:textStyle="bold" />

           </LinearLayout>

           <LinearLayout
               android:id="@+id/ll_api_calling"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="@{(v) -> clickHandler.view(v)}"
               android:orientation="vertical">

               <TextView
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:gravity="center"
                   android:text="Api Calling"
                   android:textColor="@color/black"
                   android:textStyle="bold" />

           </LinearLayout>

           <LinearLayout
               android:id="@+id/ll_database"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="@{(v) -> clickHandler.view(v)}"
               android:orientation="vertical">

               <TextView
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:gravity="center"
                   android:text="Database"
                   android:textColor="@color/black"
                   android:textStyle="bold" />

           </LinearLayout>


       </LinearLayout>

   </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Enter fullscreen mode Exit fullscreen mode

Agar aap Navigation Component ke bina ek lightweight, fast aur clean fragment system banana chahte ho, to ye approach production ready hai.
Pro Tip: Agar fragments heavy ho, to commitAllowingStateLoss() avoid karein aur state manually manage karein.

Top comments (0)