-
Notifications
You must be signed in to change notification settings - Fork 1
feat: 서재UI/UX 개편 (11) - 탭 변경 시에도 스크롤 유지되도록 기능 구현 #726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
98328fd
17689bd
9037cb9
a018d99
f2c1b80
1776fe3
b51fee3
4df8e23
34336e4
8ef02c0
de29480
1582ebf
c6454ce
13bb841
e5ae047
81a53c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,16 +1,14 @@ | ||||||||||||||||||||||||||||||||
| package com.into.websoso.ui.main | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| import android.annotation.SuppressLint | ||||||||||||||||||||||||||||||||
| import android.content.Context | ||||||||||||||||||||||||||||||||
| import android.content.Intent | ||||||||||||||||||||||||||||||||
| import android.os.Bundle | ||||||||||||||||||||||||||||||||
| import android.view.MenuItem | ||||||||||||||||||||||||||||||||
| import android.view.View | ||||||||||||||||||||||||||||||||
| import androidx.activity.OnBackPressedCallback | ||||||||||||||||||||||||||||||||
| import androidx.activity.viewModels | ||||||||||||||||||||||||||||||||
| import androidx.annotation.IntegerRes | ||||||||||||||||||||||||||||||||
| import androidx.fragment.app.Fragment | ||||||||||||||||||||||||||||||||
| import androidx.fragment.app.commit | ||||||||||||||||||||||||||||||||
| import androidx.fragment.app.replace | ||||||||||||||||||||||||||||||||
| import com.into.websoso.R.id.fcv_main | ||||||||||||||||||||||||||||||||
| import com.into.websoso.R.id.menu_explore | ||||||||||||||||||||||||||||||||
| import com.into.websoso.R.id.menu_feed | ||||||||||||||||||||||||||||||||
|
|
@@ -40,12 +38,22 @@ import dagger.hilt.android.AndroidEntryPoint | |||||||||||||||||||||||||||||||
| class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) { | ||||||||||||||||||||||||||||||||
| private val mainViewModel: MainViewModel by viewModels() | ||||||||||||||||||||||||||||||||
| private var backPressedTime: Long = 0L | ||||||||||||||||||||||||||||||||
| private var currentFragment: Fragment? = null | ||||||||||||||||||||||||||||||||
| private var currentSelectedItemId: Int = menu_home | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private val fragmentTags = mapOf( | ||||||||||||||||||||||||||||||||
| menu_home to HomeFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| menu_explore to ExploreFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| menu_feed to FeedFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| menu_library to LibraryFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| menu_my_page to MyPageFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+50
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: 각 프래그먼트에서 관리하면 좋을 것 같아요! |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| override fun onCreate(savedInstanceState: Bundle?) { | ||||||||||||||||||||||||||||||||
| super.onCreate(savedInstanceState) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| setupBackButtonListener() | ||||||||||||||||||||||||||||||||
| setBottomNavigationView() | ||||||||||||||||||||||||||||||||
| setupBottomNavigationView() | ||||||||||||||||||||||||||||||||
| setupObserver() | ||||||||||||||||||||||||||||||||
| onViewGuestClick() | ||||||||||||||||||||||||||||||||
| handleNavigation(intent.getSerializableExtra(DESTINATION_KEY) as? FragmentType) | ||||||||||||||||||||||||||||||||
|
|
@@ -75,13 +83,74 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) { | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun setBottomNavigationView() { | ||||||||||||||||||||||||||||||||
| @SuppressLint("CommitTransaction") | ||||||||||||||||||||||||||||||||
| private fun setupBottomNavigationView() { | ||||||||||||||||||||||||||||||||
| setupInitialFragment() | ||||||||||||||||||||||||||||||||
| setupBottomNavListener() | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_home | ||||||||||||||||||||||||||||||||
| replaceFragment<HomeFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun setupInitialFragment() { | ||||||||||||||||||||||||||||||||
| val initialItemId = menu_home | ||||||||||||||||||||||||||||||||
| val initialTag = fragmentTags[initialItemId]!! | ||||||||||||||||||||||||||||||||
| val initialFragment = findOrCreateFragment(initialTag) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (!initialFragment.isAdded) { | ||||||||||||||||||||||||||||||||
| supportFragmentManager | ||||||||||||||||||||||||||||||||
| .beginTransaction() | ||||||||||||||||||||||||||||||||
| .add(fcv_main, initialFragment, initialTag) | ||||||||||||||||||||||||||||||||
| .commit() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| currentFragment = initialFragment | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+93
to
+108
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: 내부에 currentFragment를 직접 관리하는 것보다, supportFragmentManager에게 현재 프래그먼트를 요청해주세요 |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun setupBottomNavListener() { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.setOnItemSelectedListener { item -> | ||||||||||||||||||||||||||||||||
| if (item.itemId == currentSelectedItemId && item.itemId == menu_library) { | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: currentSelectedItemId 로 내부 상태를 이용하기보다 supportFragmentManager를 통해 조회 및 비교해보시죠 |
||||||||||||||||||||||||||||||||
| val libraryFragment = supportFragmentManager.findFragmentByTag( | ||||||||||||||||||||||||||||||||
| LibraryFragment::class.java.name, | ||||||||||||||||||||||||||||||||
| ) as? LibraryFragment | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| libraryFragment?.resetScrollPosition() | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: fragment로 함수를 직접 호출하는 것보단, 메시지를 전달하는 구조가 좋을 것 같아요. 이렇게 구현하면, libraryFragment를 직접 find할 필요도 없겠네요 ! |
||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| replaceCurrentFragment(item.itemId) | ||||||||||||||||||||||||||||||||
| currentSelectedItemId = item.itemId | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| binding.bnvMain.setOnItemSelectedListener(::replaceFragment) | ||||||||||||||||||||||||||||||||
| true | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun replaceCurrentFragment(itemId: Int) { | ||||||||||||||||||||||||||||||||
| val tag = fragmentTags[itemId]!! | ||||||||||||||||||||||||||||||||
| val targetFragment = findOrCreateFragment(tag) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| val transaction = supportFragmentManager.beginTransaction() | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| currentFragment?.let { transaction.hide(it) } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (!targetFragment.isAdded) { | ||||||||||||||||||||||||||||||||
| transaction.add(fcv_main, targetFragment, tag) | ||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| transaction.show(targetFragment) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| transaction.commit() | ||||||||||||||||||||||||||||||||
| currentFragment = targetFragment | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+125
to
+150
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: 위랑 동일합니다! fragment dsl로 변경해주세요! |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun findOrCreateFragment(tag: String): Fragment = | ||||||||||||||||||||||||||||||||
| supportFragmentManager.findFragmentByTag(tag) | ||||||||||||||||||||||||||||||||
| ?: when (tag) { | ||||||||||||||||||||||||||||||||
| HomeFragment::class.java.name -> HomeFragment() | ||||||||||||||||||||||||||||||||
| ExploreFragment::class.java.name -> ExploreFragment() | ||||||||||||||||||||||||||||||||
| FeedFragment::class.java.name -> FeedFragment() | ||||||||||||||||||||||||||||||||
| LibraryFragment::class.java.name -> LibraryFragment() | ||||||||||||||||||||||||||||||||
| MyPageFragment::class.java.name -> MyPageFragment() | ||||||||||||||||||||||||||||||||
| else -> throw IllegalArgumentException("Unknown fragment tag: $tag") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
Comment on lines
+143
to
+161
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: 여기도 각 프래그먼트에 정의된 태그를 기반으로 ! |
||||||||||||||||||||||||||||||||
| private fun setupObserver() { | ||||||||||||||||||||||||||||||||
| mainViewModel.isLogin.observe(this) { isLogin -> | ||||||||||||||||||||||||||||||||
| when (isLogin) { | ||||||||||||||||||||||||||||||||
|
|
@@ -101,87 +170,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) { | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun replaceFragment(item: MenuItem): Boolean { | ||||||||||||||||||||||||||||||||
| when (FragmentType.valueOf(item.itemId)) { | ||||||||||||||||||||||||||||||||
| HOME -> replaceFragment<HomeFragment>() | ||||||||||||||||||||||||||||||||
| EXPLORE -> replaceFragment<ExploreFragment>() | ||||||||||||||||||||||||||||||||
| FEED -> replaceFragment<FeedFragment>() | ||||||||||||||||||||||||||||||||
| LIBRARY -> replaceFragment<LibraryFragment>() | ||||||||||||||||||||||||||||||||
| MY_PAGE -> replaceFragment<MyPageFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private inline fun <reified T : Fragment> replaceFragment() { | ||||||||||||||||||||||||||||||||
| supportFragmentManager.commit { | ||||||||||||||||||||||||||||||||
| replace<T>(fcv_main) | ||||||||||||||||||||||||||||||||
| setReorderingAllowed(true) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| enum class FragmentType( | ||||||||||||||||||||||||||||||||
| @IntegerRes private val resId: Int, | ||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||
| LIBRARY(menu_library), | ||||||||||||||||||||||||||||||||
| HOME(menu_home), | ||||||||||||||||||||||||||||||||
| EXPLORE(menu_explore), | ||||||||||||||||||||||||||||||||
| FEED(menu_feed), | ||||||||||||||||||||||||||||||||
| MY_PAGE(menu_my_page), | ||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| companion object { | ||||||||||||||||||||||||||||||||
| fun valueOf(id: Int): FragmentType = | ||||||||||||||||||||||||||||||||
| entries.find { fragmentType -> fragmentType.resId == id } | ||||||||||||||||||||||||||||||||
| ?: throw IllegalArgumentException() | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| fun valueOf(fragmentName: String): FragmentType = | ||||||||||||||||||||||||||||||||
| entries.find { fragmentType -> fragmentType.name == fragmentName } | ||||||||||||||||||||||||||||||||
| ?: throw IllegalArgumentException() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun showLoginRequestDialog() { | ||||||||||||||||||||||||||||||||
| val dialog = LoginRequestDialogFragment.newInstance() | ||||||||||||||||||||||||||||||||
| dialog.show(supportFragmentManager, LoginRequestDialogFragment.TAG) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun handleNavigation(destination: FragmentType?) { | ||||||||||||||||||||||||||||||||
| when (destination) { | ||||||||||||||||||||||||||||||||
| EXPLORE -> selectFragment(EXPLORE) | ||||||||||||||||||||||||||||||||
| MY_PAGE -> selectFragment(MY_PAGE) | ||||||||||||||||||||||||||||||||
| FEED -> selectFragment(FEED) | ||||||||||||||||||||||||||||||||
| LIBRARY -> selectFragment(LIBRARY) | ||||||||||||||||||||||||||||||||
| HOME, null -> selectFragment(HOME) | ||||||||||||||||||||||||||||||||
| val menuId = when (destination) { | ||||||||||||||||||||||||||||||||
| EXPLORE -> menu_explore | ||||||||||||||||||||||||||||||||
| MY_PAGE -> menu_my_page | ||||||||||||||||||||||||||||||||
| FEED -> menu_feed | ||||||||||||||||||||||||||||||||
| LIBRARY -> menu_library | ||||||||||||||||||||||||||||||||
| HOME, null -> menu_home | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private fun selectFragment(fragmentType: FragmentType) { | ||||||||||||||||||||||||||||||||
| when (fragmentType) { | ||||||||||||||||||||||||||||||||
| HOME -> { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_home | ||||||||||||||||||||||||||||||||
| replaceFragment<HomeFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| EXPLORE -> { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_explore | ||||||||||||||||||||||||||||||||
| replaceFragment<ExploreFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| FEED -> { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_feed | ||||||||||||||||||||||||||||||||
| replaceFragment<FeedFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| LIBRARY -> { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_library | ||||||||||||||||||||||||||||||||
| replaceFragment<LibraryFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| MY_PAGE -> { | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menu_my_page | ||||||||||||||||||||||||||||||||
| replaceFragment<MyPageFragment>() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| binding.bnvMain.selectedItemId = menuId | ||||||||||||||||||||||||||||||||
| replaceCurrentFragment(menuId) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| companion object { | ||||||||||||||||||||||||||||||||
|
|
@@ -210,4 +214,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(activity_main) { | |||||||||||||||||||||||||||||||
| flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| enum class FragmentType( | ||||||||||||||||||||||||||||||||
| @IntegerRes val resId: Int, | ||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||
| LIBRARY(menu_library), | ||||||||||||||||||||||||||||||||
| HOME(menu_home), | ||||||||||||||||||||||||||||||||
| EXPLORE(menu_explore), | ||||||||||||||||||||||||||||||||
| FEED(menu_feed), | ||||||||||||||||||||||||||||||||
| MY_PAGE(menu_my_page), | ||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| companion object { | ||||||||||||||||||||||||||||||||
| fun valueOf(id: Int): FragmentType = | ||||||||||||||||||||||||||||||||
| entries.find { it.resId == id } | ||||||||||||||||||||||||||||||||
| ?: throw IllegalArgumentException() | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| fun valueOf(fragmentName: String): FragmentType = | ||||||||||||||||||||||||||||||||
| entries.find { it.name == fragmentName } | ||||||||||||||||||||||||||||||||
| ?: throw IllegalArgumentException() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+237
to
+244
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 예외 처리 시 의미 있는 메시지 추가 예외 생성 시 구체적인 오류 메시지를 포함하여 디버깅을 용이하게 하세요. fun valueOf(id: Int): FragmentType =
entries.find { it.resId == id }
- ?: throw IllegalArgumentException()
+ ?: throw IllegalArgumentException("Unknown fragment resource id: $id")
fun valueOf(fragmentName: String): FragmentType =
entries.find { it.name == fragmentName }
- ?: throw IllegalArgumentException()
+ ?: throw IllegalArgumentException("Unknown fragment name: $fragmentName")📝 Committable suggestion
Suggested change
🧰 Tools🪛 detekt (1.23.8)[warning] 231-231: A call to the default constructor of an exception was detected. Instead one of the constructor overloads should be called. This allows to provide more meaningful exceptions. (detekt.exceptions.ThrowingExceptionsWithoutMessageOrCause) [warning] 235-235: A call to the default constructor of an exception was detected. Instead one of the constructor overloads should be called. This allows to provide more meaningful exceptions. (detekt.exceptions.ThrowingExceptionsWithoutMessageOrCause) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,10 +7,12 @@ import android.view.ViewGroup | |
| import androidx.compose.ui.platform.ComposeView | ||
| import androidx.compose.ui.platform.ViewCompositionStrategy | ||
| import androidx.fragment.app.Fragment | ||
| import androidx.fragment.app.viewModels | ||
| import com.into.websoso.R | ||
| import com.into.websoso.core.common.navigator.NavigatorProvider | ||
| import com.into.websoso.core.designsystem.theme.WebsosoTheme | ||
| import com.into.websoso.feature.library.LibraryScreen | ||
| import com.into.websoso.feature.library.LibraryViewModel | ||
| import dagger.hilt.android.AndroidEntryPoint | ||
| import javax.inject.Inject | ||
|
|
||
|
|
@@ -43,4 +45,9 @@ class LibraryFragment : Fragment() { | |
| } | ||
| return view | ||
| } | ||
|
|
||
| fun resetScrollPosition() { | ||
| val viewModel: LibraryViewModel by viewModels() | ||
| viewModel.resetScrollPosition() | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: 코드래빗 말대로 함수호출마다 매번 뷰모델을 생성하고 있어요
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 Fragment와 LibraryScreen이 같은 함수를 공유해야하니, viewModel을 매번 생성하는 것보다 Fragment에서 생성하고 Screen에 주입하는 구조가 좋을 것 같습니다! |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,10 @@ | ||
| package com.into.websoso.feature.library | ||
|
|
||
| import androidx.compose.foundation.lazy.LazyListState | ||
| import androidx.compose.foundation.lazy.grid.LazyGridState | ||
| import androidx.compose.runtime.getValue | ||
| import androidx.compose.runtime.mutableStateOf | ||
| import androidx.compose.runtime.setValue | ||
| import androidx.lifecycle.ViewModel | ||
| import androidx.lifecycle.viewModelScope | ||
| import androidx.paging.PagingData | ||
|
|
@@ -35,6 +40,12 @@ class LibraryViewModel | |
| private val _uiState = MutableStateFlow(LibraryUiState()) | ||
| val uiState: StateFlow<LibraryUiState> = _uiState.asStateFlow() | ||
|
|
||
| var listState by mutableStateOf(LazyListState()) | ||
| private set | ||
|
|
||
| var gridState by mutableStateOf(LazyGridState()) | ||
| private set | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: mutableStateOf는 Compose API입니다! 뷰모델보단 뷰에 어울리는 의존성이예요 |
||
| init { | ||
| updateMyLibraryFilter() | ||
| } | ||
|
|
@@ -88,4 +99,14 @@ class LibraryViewModel | |
| it.copy(isInterested = !it.isInterested) | ||
| } | ||
| } | ||
|
|
||
| fun resetScrollPosition() { | ||
| viewModelScope.launch { | ||
| if (uiState.value.isGrid) { | ||
| gridState.scrollToItem(0) | ||
| } else { | ||
| listState.scrollToItem(0) | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+103
to
+101
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. r: 이벤트를 전파하고, 뷰에서 이를 감지해 동작하도록 구현해도 좋겠어요 |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c: 근데 이 프로퍼티는 어디에 사용하나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replaceCurrentFragment 함수에서 사용되고 있어요!