Skip to content

Commit cfd574d

Browse files
Merge branch 'feature/add-feature-modules' into develop
2 parents 905b2fc + 7c249c2 commit cfd574d

55 files changed

Lines changed: 1214 additions & 18 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ android {
9595
jvmTarget = "1.8"
9696
}
9797

98+
dynamicFeatures = mutableSetOf(
99+
Modules.DynamicFeature.HOME,
100+
Modules.DynamicFeature.FAVORITES,
101+
Modules.DynamicFeature.NOTIFICATION,
102+
Modules.DynamicFeature.ACCOUNT
103+
)
104+
98105
testOptions {
99106
unitTests.isIncludeAndroidResources = true
100107
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.smarttoolfactory.propertyfindar
2+
3+
import android.os.Bundle
4+
import android.view.View
5+
import com.smarttoolfactory.core.ui.fragment.DynamicNavigationFragment
6+
import com.smarttoolfactory.propertyfindar.databinding.FragmentMainBinding
7+
import com.smarttoolfactory.propertyfindar.ui.BottomNavigationFragmentStateAdapter
8+
9+
class MainFragment : DynamicNavigationFragment<FragmentMainBinding>() {
10+
11+
override fun getLayoutRes(): Int = R.layout.fragment_main
12+
13+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
14+
super.onViewCreated(view, savedInstanceState)
15+
16+
val binding = dataBinding!!
17+
18+
val viewPager2 = binding.viewPager
19+
val bottomNavigationView = binding.bottomNav
20+
21+
// Cancel ViewPager swipe
22+
viewPager2.isUserInputEnabled = false
23+
24+
// Set viewpager adapter
25+
viewPager2.adapter =
26+
BottomNavigationFragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle)
27+
28+
// Listen bottom navigation tabs change
29+
bottomNavigationView.setOnNavigationItemSelectedListener {
30+
31+
when (it.itemId) {
32+
33+
R.id.nav_graph_dfm_home_start -> {
34+
viewPager2.setCurrentItem(0, false)
35+
return@setOnNavigationItemSelectedListener true
36+
}
37+
38+
R.id.nav_graph_dfm_favorites_start -> {
39+
viewPager2.setCurrentItem(1, false)
40+
return@setOnNavigationItemSelectedListener true
41+
}
42+
43+
R.id.nav_graph_dfm_notification_start -> {
44+
viewPager2.setCurrentItem(2, false)
45+
return@setOnNavigationItemSelectedListener true
46+
}
47+
48+
else -> {
49+
viewPager2.setCurrentItem(3, false)
50+
return@setOnNavigationItemSelectedListener true
51+
}
52+
}
53+
}
54+
false
55+
}
56+
57+
override fun onDestroyView() {
58+
59+
val viewPager2 = dataBinding?.viewPager
60+
61+
/*
62+
Without setting ViewPager2 Adapter it causes memory leak
63+
64+
https://stackoverflow.com/questions/62851425/viewpager2-inside-a-fragment-leaks-after-replacing-the-fragment-its-in-by-navig
65+
*/
66+
viewPager2?.let {
67+
it.adapter = null
68+
}
69+
70+
super.onDestroyView()
71+
}
72+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.smarttoolfactory.propertyfindar.ui
2+
3+
import androidx.fragment.app.Fragment
4+
import androidx.fragment.app.FragmentContainerView
5+
import androidx.fragment.app.FragmentManager
6+
import androidx.lifecycle.Lifecycle
7+
import com.smarttoolfactory.core.ui.adapter.NavigableFragmentStateAdapter
8+
import com.smarttoolfactory.core.ui.fragment.navhost.NavHostContainerFragment
9+
import com.smarttoolfactory.propertyfindar.R
10+
11+
/**
12+
* FragmentStateAdapter to contain ViewPager2 fragments inside another fragment which uses
13+
* wrapper layouts that contain [FragmentContainerView]
14+
*
15+
* * 🔥 Create FragmentStateAdapter with viewLifeCycleOwner instead of Fragment to make sure
16+
* that it lives between [Fragment.onCreateView] and [Fragment.onDestroyView] while [View] is alive
17+
*
18+
* * https://stackoverflow.com/questions/61779776/leak-canary-detects-memory-leaks-for-tablayout-with-viewpager2
19+
*/
20+
class BottomNavigationFragmentStateAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
21+
NavigableFragmentStateAdapter(fragmentManager, lifecycle) {
22+
23+
override fun getItemCount(): Int = 4
24+
25+
override fun createFragment(position: Int): Fragment {
26+
return when (position) {
27+
0 -> NavHostContainerFragment.createNavHostContainerFragment(
28+
R.layout.fragment_navhost_home,
29+
R.id.nested_nav_host_fragment_home
30+
)
31+
32+
// Vertical NavHost Post Fragment Container
33+
1 -> NavHostContainerFragment.createNavHostContainerFragment(
34+
R.layout.fragment_navhost_favorites,
35+
R.id.nested_nav_host_fragment_favorites
36+
)
37+
38+
// Horizontal NavHost Post Fragment Container
39+
2 -> NavHostContainerFragment.createNavHostContainerFragment(
40+
R.layout.fragment_navhost_notification,
41+
R.id.nested_nav_host_fragment_notification
42+
)
43+
44+
else -> NavHostContainerFragment.createNavHostContainerFragment(
45+
R.layout.fragment_navhost_account,
46+
R.id.nested_nav_host_fragment_account
47+
)
48+
}
49+
}
50+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
10+
</vector>
Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
6-
android:layout_height="match_parent"
7-
tools:context=".MainActivity">
2+
<layout>
3+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:app="http://schemas.android.com/apk/res-auto"
5+
xmlns:tools="http://schemas.android.com/tools"
6+
android:layout_width="match_parent"
7+
android:layout_height="match_parent"
8+
tools:context=".MainActivity">
89

9-
<TextView
10-
android:layout_width="wrap_content"
11-
android:layout_height="wrap_content"
12-
android:text="Hello World!"
13-
app:layout_constraintBottom_toBottomOf="parent"
14-
app:layout_constraintLeft_toLeftOf="parent"
15-
app:layout_constraintRight_toRightOf="parent"
16-
app:layout_constraintTop_toTopOf="parent" />
10+
<androidx.fragment.app.FragmentContainerView
11+
android:id="@+id/main_nav_host_fragment"
12+
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
13+
android:layout_width="0dp"
14+
android:layout_height="0dp"
15+
app:layout_constraintLeft_toLeftOf="parent"
16+
app:layout_constraintRight_toRightOf="parent"
17+
app:layout_constraintTop_toTopOf="parent"
18+
app:layout_constraintBottom_toBottomOf="parent"
1719

18-
</androidx.constraintlayout.widget.ConstraintLayout>
20+
app:defaultNavHost="true"
21+
app:navGraph="@navigation/nav_graph_main"/>
22+
23+
</androidx.constraintlayout.widget.ConstraintLayout>
24+
</layout>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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.viewpager2.widget.ViewPager2
10+
android:id="@+id/viewPager"
11+
android:layout_width="match_parent"
12+
android:layout_height="0dp"
13+
app:layout_constraintBottom_toBottomOf="parent"
14+
app:layout_constraintBottom_toTopOf="@id/bottomNav"
15+
app:layout_constraintEnd_toEndOf="parent"
16+
app:layout_constraintStart_toStartOf="parent"
17+
app:layout_constraintTop_toTopOf="parent" />
18+
19+
<com.google.android.material.bottomnavigation.BottomNavigationView
20+
android:id="@+id/bottomNav"
21+
android:layout_width="match_parent"
22+
android:layout_height="wrap_content"
23+
app:layout_constraintBottom_toBottomOf="parent"
24+
app:menu="@menu/menu_bottom" />
25+
26+
</androidx.constraintlayout.widget.ConstraintLayout>
27+
28+
</layout>
29+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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/nested_nav_host_fragment_account"
11+
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
12+
android:layout_width="0dp"
13+
android:layout_height="0dp"
14+
app:defaultNavHost="true"
15+
app:layout_constraintBottom_toBottomOf="parent"
16+
app:layout_constraintLeft_toLeftOf="parent"
17+
app:layout_constraintRight_toRightOf="parent"
18+
app:layout_constraintTop_toTopOf="parent"
19+
app:navGraph="@navigation/nav_graph_dfm_account_start" />
20+
21+
</androidx.constraintlayout.widget.ConstraintLayout>
22+
23+
</layout>

0 commit comments

Comments
 (0)