Skip to content

Commit 496826d

Browse files
add shared PropertyDetailNavigationVM for navigating different layers
1 parent c41cdba commit 496826d

9 files changed

Lines changed: 166 additions & 17 deletions

File tree

app/src/main/java/com/smarttoolfactory/propertyfindar/MainFragment.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@ package com.smarttoolfactory.propertyfindar
22

33
import android.os.Bundle
44
import android.view.View
5+
import androidx.core.os.bundleOf
6+
import androidx.fragment.app.activityViewModels
7+
import androidx.navigation.fragment.findNavController
8+
import com.google.android.material.bottomnavigation.BottomNavigationView
59
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
10+
import com.smarttoolfactory.core.util.observe
11+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
612
import com.smarttoolfactory.propertyfindar.databinding.FragmentMainBinding
713
import com.smarttoolfactory.propertyfindar.ui.BottomNavigationFragmentStateAdapter
814

915
class MainFragment : DynamicNavigationFragment<FragmentMainBinding>() {
1016

17+
/**
18+
* ViewModel for navigating to property detail screen from Main Fragment
19+
*/
20+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
21+
1122
override fun getLayoutRes(): Int = R.layout.fragment_main
1223

1324
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -51,7 +62,26 @@ class MainFragment : DynamicNavigationFragment<FragmentMainBinding>() {
5162
}
5263
}
5364
}
54-
false
65+
subscribePropertyDetailNavigation()
66+
}
67+
68+
/**
69+
* Navigates to Property Detail fragment from this fragment that replacing main fragment
70+
* that contains [BottomNavigationView]
71+
*/
72+
private fun subscribePropertyDetailNavigation() {
73+
viewLifecycleOwner.observe(propertyDetailNavigationVM.goToPropertyDetailFromMain) {
74+
75+
it.getContentIfNotHandled()?.let { propertyItem ->
76+
val bundle = bundleOf("property" to propertyItem)
77+
78+
findNavController()
79+
.navigate(
80+
R.id.action_mainFragment_to_propertyDetailFragment,
81+
bundle
82+
)
83+
}
84+
}
5585
}
5686

5787
override fun onDestroyView() {

app/src/main/res/navigation/nav_graph_main.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
android:id="@+id/mainFragment"
1010
android:name="com.smarttoolfactory.propertyfindar.MainFragment"
1111
android:label="MainFragment"
12-
tools:layout="@layout/fragment_main" />
12+
tools:layout="@layout/fragment_main">
13+
14+
<action
15+
android:id="@+id/action_mainFragment_to_propertyDetailFragment"
16+
app:destination="@id/nav_graph_property_detail" />
17+
18+
</fragment>
1319

1420

1521
<!-- Property Detail dynamic feature module -->

features/home/src/main/java/com/smarttoolfactory/home/HomeFragment.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,26 @@ import android.app.Dialog
44
import android.content.DialogInterface
55
import android.os.Bundle
66
import androidx.appcompat.app.AlertDialog
7+
import androidx.core.os.bundleOf
78
import androidx.fragment.app.DialogFragment
89
import androidx.fragment.app.Fragment
910
import androidx.fragment.app.activityViewModels
1011
import androidx.lifecycle.Observer
1112
import androidx.lifecycle.ViewModelProvider
1213
import androidx.navigation.NavController
14+
import androidx.navigation.fragment.findNavController
1315
import androidx.navigation.ui.AppBarConfiguration
1416
import androidx.navigation.ui.setupWithNavController
1517
import androidx.viewpager2.adapter.FragmentStateAdapter
1618
import androidx.viewpager2.widget.ViewPager2
19+
import com.google.android.material.bottomnavigation.BottomNavigationView
1720
import com.google.android.material.tabs.TabLayout
1821
import com.google.android.material.tabs.TabLayoutMediator
1922
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
2023
import com.smarttoolfactory.core.util.Event
24+
import com.smarttoolfactory.core.util.observe
2125
import com.smarttoolfactory.core.viewmodel.NavControllerViewModel
26+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
2227
import com.smarttoolfactory.home.adapter.HomeViewPager2FragmentStateAdapter
2328
import com.smarttoolfactory.home.databinding.FragmentHomeBinding
2429
import com.smarttoolfactory.home.viewmodel.HomeToolbarVM
@@ -53,6 +58,11 @@ class HomeFragment : DynamicNavigationFragment<FragmentHomeBinding>() {
5358
*/
5459
private val toolbarVM by activityViewModels<HomeToolbarVM>()
5560

61+
/**
62+
* ViewModel for navigating to property detail screen from Home Fragment
63+
*/
64+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
65+
5666
override fun bindViews() {
5767

5868
// ViewPager2
@@ -79,6 +89,27 @@ class HomeFragment : DynamicNavigationFragment<FragmentHomeBinding>() {
7989
setToolbarMenuItemListener()
8090

8191
subscribeAppbarNavigation()
92+
93+
subscribePropertyDetailNavigation()
94+
}
95+
96+
/**
97+
* Navigates to Property Detail fragment from this fragment that replacing main fragment
98+
* that contains [BottomNavigationView]
99+
*/
100+
private fun subscribePropertyDetailNavigation() {
101+
viewLifecycleOwner.observe(propertyDetailNavigationVM.goToPropertyDetailFromHome) {
102+
103+
it.getContentIfNotHandled()?.let { propertyItem ->
104+
val bundle = bundleOf("property" to propertyItem)
105+
106+
findNavController()
107+
.navigate(
108+
R.id.action_home_dest_to_propertyDetailFragment,
109+
bundle
110+
)
111+
}
112+
}
82113
}
83114

84115
private fun setToolbarMenuItemListener() {

features/home/src/main/java/com/smarttoolfactory/home/propertylist/flow/PropertyListFlowFragment.kt

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package com.smarttoolfactory.home.propertylist.flow
33
import android.os.Bundle
44
import androidx.core.os.bundleOf
55
import androidx.fragment.app.activityViewModels
6-
import androidx.navigation.fragment.findNavController
76
import androidx.recyclerview.widget.LinearLayoutManager
87
import com.smarttoolfactory.core.di.CoreModuleDependencies
98
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
9+
import com.smarttoolfactory.core.util.Event
1010
import com.smarttoolfactory.core.util.observe
11+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
1112
import com.smarttoolfactory.home.R
1213
import com.smarttoolfactory.home.adapter.PropertyItemListAdapter
1314
import com.smarttoolfactory.home.databinding.FragmentPropertyListBinding
@@ -21,6 +22,8 @@ class PropertyListFlowFragment : DynamicNavigationFragment<FragmentPropertyListB
2122
@Inject
2223
lateinit var viewModel: PropertyListViewModelFlow
2324

25+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
26+
2427
lateinit var itemListAdapter: PropertyItemListAdapter
2528

2629
/**
@@ -93,11 +96,32 @@ class PropertyListFlowFragment : DynamicNavigationFragment<FragmentPropertyListB
9396
{
9497

9598
it.getContentIfNotHandled()?.let { propertyItem ->
99+
96100
val bundle = bundleOf("property" to propertyItem)
97-
findNavController().navigate(
98-
R.id.action_propertyListFragment_to_nav_graph_property_detail,
99-
bundle
100-
)
101+
/*
102+
* This is the navController belong to Home
103+
*/
104+
105+
// Alternative 1 getting grand grand parent fragment of this fragment
106+
// try {
107+
// val homeFragment = parentFragment?.parentFragment?.parentFragment
108+
//
109+
// (homeFragment as? HomeFragment)?.findNavController()?.navigate(
110+
// R.id.action_home_dest_to_propertyDetailFragment,
111+
// bundle
112+
// )
113+
//
114+
// } catch (e: Exception) {
115+
// findNavController()
116+
// .navigate(
117+
// R.id.action_propertyListFragment_to_nav_graph_property_detail,
118+
// bundle
119+
// )
120+
// }
121+
122+
// Alternative 2 use ViewModel
123+
propertyDetailNavigationVM.goToPropertyDetailFromMain.value =
124+
(Event(propertyItem))
101125
}
102126
}
103127
)

features/home/src/main/java/com/smarttoolfactory/home/propertylist/paged/PagedPropertyListFragment.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.smarttoolfactory.core.di.CoreModuleDependencies
99
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
1010
import com.smarttoolfactory.core.util.EndlessScrollListener
1111
import com.smarttoolfactory.core.util.observe
12+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
1213
import com.smarttoolfactory.home.R
1314
import com.smarttoolfactory.home.adapter.PropertyItemListAdapter
1415
import com.smarttoolfactory.home.databinding.FragmentPropertyListPagedBinding
@@ -24,6 +25,8 @@ class PagedPropertyListFragment :
2425
@Inject
2526
lateinit var viewModel: PagedPropertyListViewModel
2627

28+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
29+
2730
lateinit var itemListAdapter: PropertyItemListAdapter
2831

2932
/**

features/home/src/main/java/com/smarttoolfactory/home/propertylist/rxjava/PropertyListRxjava3Fragment.kt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.smarttoolfactory.home.propertylist.rxjava
22

33
import android.os.Bundle
4-
import androidx.core.os.bundleOf
54
import androidx.fragment.app.activityViewModels
6-
import androidx.navigation.fragment.findNavController
75
import androidx.recyclerview.widget.LinearLayoutManager
86
import com.smarttoolfactory.core.di.CoreModuleDependencies
97
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
8+
import com.smarttoolfactory.core.util.Event
109
import com.smarttoolfactory.core.util.observe
10+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
1111
import com.smarttoolfactory.home.R
1212
import com.smarttoolfactory.home.adapter.PropertyItemListAdapter
1313
import com.smarttoolfactory.home.databinding.FragmentPropertyListBinding
@@ -21,6 +21,8 @@ class PropertyListRxjava3Fragment : DynamicNavigationFragment<FragmentPropertyLi
2121
@Inject
2222
lateinit var viewModel: PropertyListViewModelRxJava3
2323

24+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
25+
2426
lateinit var itemListAdapter: PropertyItemListAdapter
2527

2628
/**
@@ -85,19 +87,18 @@ class PropertyListRxjava3Fragment : DynamicNavigationFragment<FragmentPropertyLi
8587
}
8688
}
8789
}
88-
8990
private fun subscribeGoToDetailScreen() {
9091

9192
viewModel.goToDetailScreen.observe(
9293
viewLifecycleOwner,
9394
{
94-
9595
it.getContentIfNotHandled()?.let { propertyItem ->
96-
val bundle = bundleOf("property" to propertyItem)
97-
findNavController().navigate(
98-
R.id.action_propertyListFragment_to_nav_graph_property_detail,
99-
bundle
100-
)
96+
/*
97+
Navigates from Main fragment of the app which replaces everything with
98+
detail
99+
*/
100+
propertyDetailNavigationVM.goToPropertyDetailFromHome.value =
101+
(Event(propertyItem))
101102
}
102103
}
103104
)

features/home/src/main/res/navigation/nav_graph_home.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,23 @@
1010
android:id="@+id/homeFragment"
1111
android:name="com.smarttoolfactory.home.HomeFragment"
1212
android:label="HomeFragment"
13-
tools:layout="@layout/fragment_home" />
13+
tools:layout="@layout/fragment_home">
14+
15+
<action
16+
android:id="@+id/action_home_dest_to_propertyDetailFragment"
17+
app:destination="@id/nav_graph_property_detail" />
18+
19+
</fragment>
20+
21+
<include-dynamic
22+
android:id="@id/nav_graph_property_detail"
23+
android:name="com.smarttoolfactory.property_detail"
24+
app:graphResName="nav_graph_property_detail"
25+
app:moduleName="property_detail">
26+
27+
<argument
28+
android:name="property"
29+
app:argType="com.smarttoolfactory.domain.model.PropertyItem" />
30+
31+
</include-dynamic>
1432
</navigation>

libraries/core/src/main/java/com/smarttoolfactory/core/viewmodel/NavControllerViewModel.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import androidx.lifecycle.ViewModel
55
import androidx.navigation.NavController
66
import com.smarttoolfactory.core.util.Event
77

8+
/**
9+
* ViewModel shared by Activity and fragmgents that contains the [NavController] belongs to
10+
* current fragment on screen.
11+
*
12+
* * Usable to change Toolbar status based on fragment currently navigated
13+
*/
814
class NavControllerViewModel : ViewModel() {
915
val currentNavController = MutableLiveData<Event<NavController?>>()
1016
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.smarttoolfactory.core.viewmodel
2+
3+
import androidx.lifecycle.MutableLiveData
4+
import androidx.lifecycle.ViewModel
5+
import com.smarttoolfactory.core.util.Event
6+
import com.smarttoolfactory.domain.model.PropertyItem
7+
8+
/**
9+
* ViewModel for navigating to detail from different layers of the app. When the [PropertyItem]
10+
*
11+
* of this model is set from a list fragment specified can navigate to detail screen
12+
*
13+
* * Navigate from Main fragment in **App module**
14+
* that replaces the one that contains BottomNavigationView
15+
*
16+
* * Navigate from Home fragment in **Home module** that contains ViewPager2
17+
* * Navigate from individual property list fragments
18+
*/
19+
class PropertyDetailNavigationVM : ViewModel() {
20+
21+
/**
22+
* LiveData to navigate Property detail from MainFragment in app module
23+
*/
24+
val goToPropertyDetailFromMain = MutableLiveData<Event<PropertyItem?>>()
25+
26+
/**
27+
* LiveData to navigate Property detail from HomeFragment in Home dynamic feature module
28+
*/
29+
val goToPropertyDetailFromHome = MutableLiveData<Event<PropertyItem?>>()
30+
}

0 commit comments

Comments
 (0)