Skip to content

Commit d032c5f

Browse files
Merge branch 'release/v1.0.1'
2 parents 6f3850e + 1d9e412 commit d032c5f

File tree

11 files changed

+194
-21
lines changed

11 files changed

+194
-21
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.smarttoolfactory.propertyfindar
2+
3+
import android.os.Bundle
4+
import android.view.View
5+
import androidx.core.os.bundleOf
6+
import androidx.fragment.app.activityViewModels
7+
import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
8+
import androidx.navigation.fragment.findNavController
9+
import com.google.android.material.bottomnavigation.BottomNavigationView
10+
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
11+
import com.smarttoolfactory.core.ui.fragment.navhost.BaseDynamicNavHostFragment
12+
import com.smarttoolfactory.core.util.observe
13+
import com.smarttoolfactory.core.util.setupWithNavController
14+
import com.smarttoolfactory.core.viewmodel.PropertyDetailNavigationVM
15+
import com.smarttoolfactory.propertyfindar.databinding.FragmentMainBottomNavBinding
16+
17+
/**
18+
* Alternative of MainFragment with only [BottomNavigationView]
19+
* that has [DynamicNavHostFragment]s as root fragment of each
20+
* tab with [BaseDynamicNavHostFragment]s that extend [DynamicNavHostFragment].
21+
*
22+
*
23+
*/
24+
class MainFragmentBottomNav : DynamicNavigationFragment<FragmentMainBottomNavBinding>() {
25+
26+
/**
27+
* ViewModel for navigating to property detail screen from Main Fragment
28+
*/
29+
private val propertyDetailNavigationVM by activityViewModels<PropertyDetailNavigationVM>()
30+
31+
override fun getLayoutRes(): Int = R.layout.fragment_main_bottom_nav
32+
33+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34+
super.onViewCreated(view, savedInstanceState)
35+
36+
if (savedInstanceState == null) {
37+
setupBottomNavigationBar()
38+
} // Else, need to wait for onRestoreInstanceState
39+
40+
subscribePropertyDetailNavigation()
41+
}
42+
43+
override fun onViewStateRestored(savedInstanceState: Bundle?) {
44+
super.onViewStateRestored(savedInstanceState)
45+
// Now that BottomNavigationBar has restored its instance state
46+
// and its selectedItemId, we can proceed with setting up the
47+
// BottomNavigationBar with Navigation
48+
setupBottomNavigationBar()
49+
}
50+
51+
/**
52+
* Called on first creation and when restoring state.
53+
*/
54+
private fun setupBottomNavigationBar() {
55+
56+
val bottomNavigationView = dataBinding!!.bottomNav
57+
58+
val navGraphIds = listOf(
59+
R.navigation.nav_graph_dfm_home_start,
60+
R.navigation.nav_graph_dfm_favorites_start,
61+
R.navigation.nav_graph_dfm_notification_start,
62+
R.navigation.nav_graph_dfm_account_start
63+
)
64+
65+
// Setup the bottom navigation view with a list of navigation graphs
66+
val controller = bottomNavigationView.setupWithNavController(
67+
navGraphIds = navGraphIds,
68+
fragmentManager = childFragmentManager,
69+
containerId = R.id.nav_host_container,
70+
intent = requireActivity().intent
71+
)
72+
}
73+
74+
/**
75+
* Navigates to Property Detail fragment from this fragment that replacing main fragment
76+
* that contains [BottomNavigationView]
77+
*/
78+
private fun subscribePropertyDetailNavigation() {
79+
80+
viewLifecycleOwner.observe(propertyDetailNavigationVM.goToPropertyDetailFromMain) {
81+
82+
it.getContentIfNotHandled()?.let { propertyItem ->
83+
val bundle = bundleOf("property" to propertyItem)
84+
85+
findNavController()
86+
.navigate(
87+
R.id.action_mainFragment_to_propertyDetailFragment,
88+
bundle
89+
)
90+
}
91+
}
92+
}
93+
}

app/src/main/res/layout/activity_main.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
app:layout_constraintBottom_toBottomOf="parent"
1919

2020
app:defaultNavHost="true"
21-
app:navGraph="@navigation/nav_graph_main"/>
21+
app:navGraph="@navigation/nav_graph_main_bottom_nav"/>
2222

2323
</androidx.constraintlayout.widget.ConstraintLayout>
2424
</layout>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto">
4+
5+
<androidx.constraintlayout.widget.ConstraintLayout
6+
android:layout_width="match_parent"
7+
android:layout_height="match_parent">
8+
9+
<androidx.fragment.app.FragmentContainerView
10+
android:id="@+id/nav_host_container"
11+
android:layout_width="0dp"
12+
android:layout_height="0dp"
13+
app:layout_constraintBottom_toTopOf="@+id/bottomNav"
14+
app:layout_constraintLeft_toLeftOf="parent"
15+
app:layout_constraintRight_toRightOf="parent"
16+
app:layout_constraintTop_toTopOf="parent" />
17+
18+
<com.google.android.material.bottomnavigation.BottomNavigationView
19+
android:id="@+id/bottomNav"
20+
android:layout_width="match_parent"
21+
android:layout_height="wrap_content"
22+
app:layout_constraintBottom_toBottomOf="parent"
23+
app:menu="@menu/menu_bottom" />
24+
25+
</androidx.constraintlayout.widget.ConstraintLayout>
26+
27+
</layout>
28+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:id="@+id/nav_graph_main_bottom_bottom_nav"
6+
app:startDestination="@id/mainFragment">
7+
8+
9+
<fragment
10+
android:id="@+id/mainFragment"
11+
android:name="com.smarttoolfactory.propertyfindar.MainFragmentBottomNav"
12+
android:label="MainFragment"
13+
tools:layout="@layout/fragment_main">
14+
15+
<action
16+
android:id="@+id/action_mainFragment_to_propertyDetailFragment"
17+
app:destination="@id/nav_graph_property_detail"
18+
app:enterAnim="@anim/slide_in_right"
19+
app:exitAnim="@anim/slide_out_left"
20+
app:popEnterAnim="@anim/slide_in_left"
21+
app:popExitAnim="@anim/slide_out_right" />
22+
23+
</fragment>
24+
25+
26+
<!-- Property Detail dynamic feature module -->
27+
<include-dynamic
28+
android:id="@+id/nav_graph_property_detail"
29+
android:name="com.smarttoolfactory.property_detail"
30+
app:graphResName="nav_graph_property_detail"
31+
app:moduleName="property_detail">
32+
33+
<argument
34+
android:name="property"
35+
app:argType="com.smarttoolfactory.domain.model.PropertyItem" />
36+
37+
</include-dynamic>
38+
</navigation>

config/detekt/detekt.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ complexity:
105105
TooManyFunctions:
106106
active: true
107107
excludes: ['**/test/**', '**/test-utils/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
108-
thresholdInFiles: 11
109-
thresholdInClasses: 11
110-
thresholdInInterfaces: 11
111-
thresholdInObjects: 11
112-
thresholdInEnums: 11
108+
thresholdInFiles: 12
109+
thresholdInClasses: 12
110+
thresholdInInterfaces: 12
111+
thresholdInObjects: 12
112+
thresholdInEnums: 12
113113
ignoreDeprecated: false
114114
ignorePrivate: false
115115
ignoreOverridden: false

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ class PropertyListFlowFragment : DynamicNavigationFragment<FragmentPropertyListB
4040
}
4141

4242
override fun bindViews() {
43-
dataBinding.viewModel = viewModel
43+
dataBinding!!.viewModel = viewModel
4444

45-
dataBinding.recyclerView.apply {
45+
dataBinding!!.recyclerView.apply {
4646

4747
// Set Layout manager
4848
this.layoutManager =
@@ -58,7 +58,7 @@ class PropertyListFlowFragment : DynamicNavigationFragment<FragmentPropertyListB
5858
this.adapter = itemListAdapter
5959
}
6060

61-
val swipeRefreshLayout = dataBinding.swipeRefreshLayout
61+
val swipeRefreshLayout = dataBinding!!.swipeRefreshLayout
6262

6363
swipeRefreshLayout.setOnRefreshListener {
6464
swipeRefreshLayout.isRefreshing = false
@@ -150,4 +150,9 @@ class PropertyListFlowFragment : DynamicNavigationFragment<FragmentPropertyListB
150150
super.onPause()
151151
toolbarVM.queryBySort.removeObservers(viewLifecycleOwner)
152152
}
153+
154+
override fun onDestroyView() {
155+
dataBinding!!.swipeRefreshLayout.setOnRefreshListener(null)
156+
super.onDestroyView()
157+
}
153158
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ class PagedPropertyListFragment :
4848
}
4949

5050
override fun bindViews() {
51-
dataBinding.viewModel = viewModel
51+
dataBinding!!.viewModel = viewModel
5252

53-
dataBinding.recyclerView.apply {
53+
dataBinding!!.recyclerView.apply {
5454

5555
// Set Layout manager
5656
val linearLayoutManager =
@@ -75,7 +75,7 @@ class PagedPropertyListFragment :
7575
this.addOnScrollListener(endlessScrollListener)
7676
}
7777

78-
val swipeRefreshLayout = dataBinding.swipeRefreshLayout
78+
val swipeRefreshLayout = dataBinding!!.swipeRefreshLayout
7979

8080
swipeRefreshLayout.setOnRefreshListener {
8181
swipeRefreshLayout.isRefreshing = false
@@ -150,4 +150,9 @@ class PagedPropertyListFragment :
150150
override fun onScrollToBottom() {
151151
viewModel.getPropertyList()
152152
}
153+
154+
override fun onDestroyView() {
155+
dataBinding!!.swipeRefreshLayout.setOnRefreshListener(null)
156+
super.onDestroyView()
157+
}
153158
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ class PropertyListRxjava3Fragment : DynamicNavigationFragment<FragmentPropertyLi
3939
}
4040

4141
override fun bindViews() {
42-
dataBinding.viewModel = viewModel
42+
dataBinding!!.viewModel = viewModel
4343

44-
dataBinding.recyclerView.apply {
44+
dataBinding!!.recyclerView.apply {
4545

4646
// Set Layout manager
4747
this.layoutManager =
@@ -57,7 +57,7 @@ class PropertyListRxjava3Fragment : DynamicNavigationFragment<FragmentPropertyLi
5757
this.adapter = itemListAdapter
5858
}
5959

60-
val swipeRefreshLayout = dataBinding.swipeRefreshLayout
60+
val swipeRefreshLayout = dataBinding!!.swipeRefreshLayout
6161

6262
swipeRefreshLayout.setOnRefreshListener {
6363
swipeRefreshLayout.isRefreshing = false
@@ -127,4 +127,9 @@ class PropertyListRxjava3Fragment : DynamicNavigationFragment<FragmentPropertyLi
127127
super.onPause()
128128
toolbarVM.queryBySort.removeObservers(viewLifecycleOwner)
129129
}
130+
131+
override fun onDestroyView() {
132+
dataBinding!!.swipeRefreshLayout.setOnRefreshListener(null)
133+
super.onDestroyView()
134+
}
130135
}

features/property_detail/src/main/java/com/smarttoolfactory/property_detail/PropertyDetailFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class PropertyDetailFragment : DynamicNavigationFragment<FragmentPropertyDetailB
2727
override fun bindViews() {
2828
// Get Post from navigation component arguments
2929
val property = arguments?.get("property") as PropertyItem
30-
dataBinding.item = property
30+
dataBinding!!.item = property
3131
}
3232

3333
override fun onCreate(savedInstanceState: Bundle?) {

libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/BaseDataBindingFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ abstract class BaseDataBindingFragment<ViewBinding : ViewDataBinding> : Fragment
3333

3434
private var _dataBinding: ViewBinding? = null
3535

36-
lateinit var dataBinding: ViewBinding
36+
var dataBinding: ViewBinding? = null
3737

3838
/**
3939
* 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<ViewBinding : ViewDataBinding> : Fragment
6767
* again, and when onDestroyView is called removes this binding to liveData
6868
* since it's bound to View instead of Fragment(this).
6969
*/
70-
dataBinding.lifecycleOwner = viewLifecycleOwner
70+
dataBinding!!.lifecycleOwner = viewLifecycleOwner
7171

72-
val rootView = dataBinding.root
72+
val rootView = dataBinding!!.root
7373

7474
// Get width and height of the fragment
7575
rootView.post {

libraries/core/src/main/java/com/smarttoolfactory/core/ui/fragment/navhost/BaseDynamicNavHostFragment.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.os.Bundle
44
import androidx.annotation.NavigationRes
55
import androidx.fragment.app.activityViewModels
66
import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
7-
import androidx.navigation.fragment.NavHostFragment
87
import com.smarttoolfactory.core.error.NavigationException
98
import com.smarttoolfactory.core.util.Event
109
import com.smarttoolfactory.core.viewmodel.NavControllerViewModel
@@ -14,7 +13,7 @@ import com.smarttoolfactory.core.viewmodel.NavControllerViewModel
1413
* uses [BaseDynamicNavHostFragment.createDynamicNavHostFragment] function with navigation graph
1514
* parameter
1615
*/
17-
class BaseDynamicNavHostFragment : NavHostFragment() {
16+
class BaseDynamicNavHostFragment : DynamicNavHostFragment() {
1817

1918
private val navControllerViewModel by activityViewModels<NavControllerViewModel>()
2019

0 commit comments

Comments
 (0)