diff --git a/app/src/main/java/com/smarttoolfactory/propertyfindar/MainFragmentBottomNav.kt b/app/src/main/java/com/smarttoolfactory/propertyfindar/MainFragmentBottomNav.kt new file mode 100644 index 0000000..d4030ce --- /dev/null +++ b/app/src/main/java/com/smarttoolfactory/propertyfindar/MainFragmentBottomNav.kt @@ -0,0 +1,93 @@ +package com.smarttoolfactory.propertyfindar + +import android.os.Bundle +import android.view.View +import androidx.core.os.bundleOf +import androidx.fragment.app.activityViewModels +import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment +import androidx.navigation.fragment.findNavController +import com.google.android.material.bottomnavigation.BottomNavigationView +import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment +import com.smarttoolfactory.core.ui.fragment.navhost.BaseDynamicNavHostFragment +import com.smarttoolfactory.core.util.observe +import com.smarttoolfactory.core.util.setupWithNavController +import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM +import com.smarttoolfactory.propertyfindar.databinding.FragmentMainBottomNavBinding + +/** + * Alternative of MainFragment with only [BottomNavigationView] + * that has [DynamicNavHostFragment]s as root fragment of each + * tab with [BaseDynamicNavHostFragment]s that extend [DynamicNavHostFragment]. + * + * + */ +class MainFragmentBottomNav : DynamicNavigationFragment() { + + /** + * ViewModel for navigating to property detail screen from Main Fragment + */ + private val propertyDetailNavigationVM by activityViewModels() + + override fun getLayoutRes(): Int = R.layout.fragment_main_bottom_nav + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + if (savedInstanceState == null) { + setupBottomNavigationBar() + } // Else, need to wait for onRestoreInstanceState + + subscribePropertyDetailNavigation() + } + + override fun onViewStateRestored(savedInstanceState: Bundle?) { + super.onViewStateRestored(savedInstanceState) + // Now that BottomNavigationBar has restored its instance state + // and its selectedItemId, we can proceed with setting up the + // BottomNavigationBar with Navigation + setupBottomNavigationBar() + } + + /** + * Called on first creation and when restoring state. + */ + private fun setupBottomNavigationBar() { + + val bottomNavigationView = dataBinding!!.bottomNav + + val navGraphIds = listOf( + R.navigation.nav_graph_dfm_home_start, + R.navigation.nav_graph_dfm_favorites_start, + R.navigation.nav_graph_dfm_notification_start, + R.navigation.nav_graph_dfm_account_start + ) + + // Setup the bottom navigation view with a list of navigation graphs + val controller = bottomNavigationView.setupWithNavController( + navGraphIds = navGraphIds, + fragmentManager = childFragmentManager, + containerId = R.id.nav_host_container, + intent = requireActivity().intent + ) + } + + /** + * Navigates to Property Detail fragment from this fragment that replacing main fragment + * that contains [BottomNavigationView] + */ + private fun subscribePropertyDetailNavigation() { + + viewLifecycleOwner.observe(propertyDetailNavigationVM.goToPropertyDetailFromMain) { + + it.getContentIfNotHandled()?.let { propertyItem -> + val bundle = bundleOf("property" to propertyItem) + + findNavController() + .navigate( + R.id.action_mainFragment_to_propertyDetailFragment, + bundle + ) + } + } + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e33589b..5dea676 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -18,7 +18,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" - app:navGraph="@navigation/nav_graph_main"/> + app:navGraph="@navigation/nav_graph_main_bottom_nav"/> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main_bottom_nav.xml b/app/src/main/res/layout/fragment_main_bottom_nav.xml new file mode 100644 index 0000000..e7c3f32 --- /dev/null +++ b/app/src/main/res/layout/fragment_main_bottom_nav.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph_main_bottom_nav.xml b/app/src/main/res/navigation/nav_graph_main_bottom_nav.xml new file mode 100644 index 0000000..66d6102 --- /dev/null +++ b/app/src/main/res/navigation/nav_graph_main_bottom_nav.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 0070e69..6bd8421 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -105,11 +105,11 @@ complexity: TooManyFunctions: active: true excludes: ['**/test/**', '**/test-utils/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - thresholdInFiles: 11 - thresholdInClasses: 11 - thresholdInInterfaces: 11 - thresholdInObjects: 11 - thresholdInEnums: 11 + thresholdInFiles: 12 + thresholdInClasses: 12 + thresholdInInterfaces: 12 + thresholdInObjects: 12 + thresholdInEnums: 12 ignoreDeprecated: false ignorePrivate: false ignoreOverridden: false diff --git a/features/home/src/main/java/com/smarttoolfactory/home/propertylist/flow/PropertyListFlowFragment.kt b/features/home/src/main/java/com/smarttoolfactory/home/propertylist/flow/PropertyListFlowFragment.kt index 66b2d93..ee1c685 100644 --- a/features/home/src/main/java/com/smarttoolfactory/home/propertylist/flow/PropertyListFlowFragment.kt +++ b/features/home/src/main/java/com/smarttoolfactory/home/propertylist/flow/PropertyListFlowFragment.kt @@ -40,9 +40,9 @@ class PropertyListFlowFragment : DynamicNavigationFragment : Fragment private var _dataBinding: ViewBinding? = null - lateinit var dataBinding: ViewBinding + var dataBinding: ViewBinding? = null /** * This method gets the layout id from the derived fragment to bind to that layout via data-binding @@ -67,9 +67,9 @@ abstract class BaseDataBindingFragment : Fragment * again, and when onDestroyView is called removes this binding to liveData * since it's bound to View instead of Fragment(this). */ - dataBinding.lifecycleOwner = viewLifecycleOwner + dataBinding!!.lifecycleOwner = viewLifecycleOwner - val rootView = dataBinding.root + val rootView = dataBinding!!.root // Get width and height of the fragment rootView.post { diff --git a/libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/navhost/BaseDynamicNavHostFragment.kt b/libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/navhost/BaseDynamicNavHostFragment.kt index c8db2e5..9e22c19 100644 --- a/libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/navhost/BaseDynamicNavHostFragment.kt +++ b/libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/navhost/BaseDynamicNavHostFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import androidx.annotation.NavigationRes import androidx.fragment.app.activityViewModels import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment -import androidx.navigation.fragment.NavHostFragment import com.smarttoolfactory.core.error.NavigationException import com.smarttoolfactory.core.util.Event import com.smarttoolfactory.core.viewmodel.NavControllerViewModel @@ -14,7 +13,7 @@ import com.smarttoolfactory.core.viewmodel.NavControllerViewModel * uses [BaseDynamicNavHostFragment.createDynamicNavHostFragment] function with navigation graph * parameter */ -class BaseDynamicNavHostFragment : NavHostFragment() { +class BaseDynamicNavHostFragment : DynamicNavHostFragment() { private val navControllerViewModel by activityViewModels()