11package com.into.websoso.ui.main
22
3+ import android.annotation.SuppressLint
34import android.content.Context
45import android.content.Intent
56import android.os.Bundle
6- import android.view.MenuItem
77import android.view.View
88import androidx.activity.OnBackPressedCallback
99import androidx.activity.viewModels
10- import androidx.annotation.DrawableRes
10+ import androidx.annotation.IntegerRes
1111import androidx.fragment.app.Fragment
12- import androidx.fragment.app.commit
13- import androidx.fragment.app.replace
1412import com.into.websoso.R.id.fcv_main
1513import com.into.websoso.R.id.menu_explore
1614import com.into.websoso.R.id.menu_feed
@@ -40,12 +38,22 @@ import dagger.hilt.android.AndroidEntryPoint
4038class MainActivity : BaseActivity <ActivityMainBinding >(activity_main) {
4139 private val mainViewModel: MainViewModel by viewModels()
4240 private var backPressedTime: Long = 0L
41+ private var currentFragment: Fragment ? = null
42+ private var currentSelectedItemId: Int = menu_home
43+
44+ private val fragmentTags = mapOf (
45+ menu_home to HomeFragment ::class .java.name,
46+ menu_explore to ExploreFragment ::class .java.name,
47+ menu_feed to FeedFragment ::class .java.name,
48+ menu_library to LibraryFragment ::class .java.name,
49+ menu_my_page to MyPageFragment ::class .java.name,
50+ )
4351
4452 override fun onCreate (savedInstanceState : Bundle ? ) {
4553 super .onCreate(savedInstanceState)
4654
4755 setupBackButtonListener()
48- setBottomNavigationView ()
56+ setupBottomNavigationView ()
4957 setupObserver()
5058 onViewGuestClick()
5159 handleNavigation(intent.getSerializableExtra(DESTINATION_KEY ) as ? FragmentType )
@@ -75,13 +83,74 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) {
7583 }
7684 }
7785
78- private fun setBottomNavigationView () {
86+ @SuppressLint(" CommitTransaction" )
87+ private fun setupBottomNavigationView () {
88+ setupInitialFragment()
89+ setupBottomNavListener()
7990 binding.bnvMain.selectedItemId = menu_home
80- replaceFragment<HomeFragment >()
91+ }
92+
93+ private fun setupInitialFragment () {
94+ val initialItemId = menu_home
95+ val initialTag = fragmentTags[initialItemId]!!
96+ val initialFragment = findOrCreateFragment(initialTag)
97+
98+ if (! initialFragment.isAdded) {
99+ supportFragmentManager
100+ .beginTransaction()
101+ .add(fcv_main, initialFragment, initialTag)
102+ .commit()
103+ }
104+
105+ currentFragment = initialFragment
106+ }
107+
108+ private fun setupBottomNavListener () {
109+ binding.bnvMain.setOnItemSelectedListener { item ->
110+ if (item.itemId == currentSelectedItemId && item.itemId == menu_library) {
111+ val libraryFragment = supportFragmentManager.findFragmentByTag(
112+ LibraryFragment ::class .java.name,
113+ ) as ? LibraryFragment
114+
115+ libraryFragment?.resetScrollPosition()
116+ } else {
117+ replaceCurrentFragment(item.itemId)
118+ currentSelectedItemId = item.itemId
119+ }
81120
82- binding.bnvMain.setOnItemSelectedListener(::replaceFragment)
121+ true
122+ }
83123 }
84124
125+ private fun replaceCurrentFragment (itemId : Int ) {
126+ val tag = fragmentTags[itemId]!!
127+ val targetFragment = findOrCreateFragment(tag)
128+
129+ val transaction = supportFragmentManager.beginTransaction()
130+
131+ currentFragment?.let { transaction.hide(it) }
132+
133+ if (! targetFragment.isAdded) {
134+ transaction.add(fcv_main, targetFragment, tag)
135+ } else {
136+ transaction.show(targetFragment)
137+ }
138+
139+ transaction.commit()
140+ currentFragment = targetFragment
141+ }
142+
143+ private fun findOrCreateFragment (tag : String ): Fragment =
144+ supportFragmentManager.findFragmentByTag(tag)
145+ ? : when (tag) {
146+ HomeFragment ::class .java.name -> HomeFragment ()
147+ ExploreFragment ::class .java.name -> ExploreFragment ()
148+ FeedFragment ::class .java.name -> FeedFragment ()
149+ LibraryFragment ::class .java.name -> LibraryFragment ()
150+ MyPageFragment ::class .java.name -> MyPageFragment ()
151+ else -> throw IllegalArgumentException (" Unknown fragment tag: $tag " )
152+ }
153+
85154 private fun setupObserver () {
86155 mainViewModel.isLogin.observe(this ) { isLogin ->
87156 when (isLogin) {
@@ -101,87 +170,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) {
101170 }
102171 }
103172
104- private fun replaceFragment (item : MenuItem ): Boolean {
105- when (FragmentType .valueOf(item.itemId)) {
106- HOME -> replaceFragment<HomeFragment >()
107- EXPLORE -> replaceFragment<ExploreFragment >()
108- FEED -> replaceFragment<FeedFragment >()
109- LIBRARY -> replaceFragment<LibraryFragment >()
110- MY_PAGE -> replaceFragment<MyPageFragment >()
111- }
112- return true
113- }
114-
115- private inline fun <reified T : Fragment > replaceFragment () {
116- supportFragmentManager.commit {
117- replace<T >(fcv_main)
118- setReorderingAllowed(true )
119- }
120- }
121-
122- enum class FragmentType (
123- @DrawableRes private val resId : Int ,
124- ) {
125- LIBRARY (menu_library),
126- HOME (menu_home),
127- EXPLORE (menu_explore),
128- FEED (menu_feed),
129- MY_PAGE (menu_my_page),
130- ;
131-
132- companion object {
133- fun valueOf (id : Int ): FragmentType =
134- entries.find { fragmentType -> fragmentType.resId == id }
135- ? : throw IllegalArgumentException ()
136-
137- fun valueOf (fragmentName : String ): FragmentType =
138- entries.find { fragmentType -> fragmentType.name == fragmentName }
139- ? : throw IllegalArgumentException ()
140- }
141- }
142-
143173 private fun showLoginRequestDialog () {
144174 val dialog = LoginRequestDialogFragment .newInstance()
145175 dialog.show(supportFragmentManager, LoginRequestDialogFragment .TAG )
146176 }
147177
148178 private fun handleNavigation (destination : FragmentType ? ) {
149- when (destination) {
150- EXPLORE -> selectFragment( EXPLORE )
151- MY_PAGE -> selectFragment( MY_PAGE )
152- FEED -> selectFragment( FEED )
153- LIBRARY -> selectFragment( LIBRARY )
154- HOME , null -> selectFragment( HOME )
179+ val menuId = when (destination) {
180+ EXPLORE -> menu_explore
181+ MY_PAGE -> menu_my_page
182+ FEED -> menu_feed
183+ LIBRARY -> menu_library
184+ HOME , null -> menu_home
155185 }
156- }
157-
158- private fun selectFragment (fragmentType : FragmentType ) {
159- when (fragmentType) {
160- HOME -> {
161- binding.bnvMain.selectedItemId = menu_home
162- replaceFragment<HomeFragment >()
163- }
164-
165- EXPLORE -> {
166- binding.bnvMain.selectedItemId = menu_explore
167- replaceFragment<ExploreFragment >()
168- }
169-
170- FEED -> {
171- binding.bnvMain.selectedItemId = menu_feed
172- replaceFragment<FeedFragment >()
173- }
174186
175- LIBRARY -> {
176- binding.bnvMain.selectedItemId = menu_library
177- replaceFragment<LibraryFragment >()
178- }
179-
180- MY_PAGE -> {
181- binding.bnvMain.selectedItemId = menu_my_page
182- replaceFragment<MyPageFragment >()
183- }
184- }
187+ binding.bnvMain.selectedItemId = menuId
188+ replaceCurrentFragment(menuId)
185189 }
186190
187191 companion object {
@@ -210,4 +214,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) {
210214 flags = Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TASK
211215 }
212216 }
217+
218+ enum class FragmentType (
219+ @IntegerRes val resId : Int ,
220+ ) {
221+ LIBRARY (menu_library),
222+ HOME (menu_home),
223+ EXPLORE (menu_explore),
224+ FEED (menu_feed),
225+ MY_PAGE (menu_my_page),
226+ ;
227+
228+ companion object {
229+ fun valueOf (id : Int ): FragmentType =
230+ entries.find { it.resId == id }
231+ ? : throw IllegalArgumentException ()
232+
233+ fun valueOf (fragmentName : String ): FragmentType =
234+ entries.find { it.name == fragmentName }
235+ ? : throw IllegalArgumentException ()
236+ }
237+ }
213238}
0 commit comments