From 250ab1f5df4c59f303d820c29184d6325c1392c9 Mon Sep 17 00:00:00 2001 From: aurora32s Date: Sun, 8 Oct 2023 16:38:36 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[FIX]=20#117=20-=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EA=B2=80=EC=83=89=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EC=9D=B4=20=EC=B4=88=EA=B8=B0=ED=99=94=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/peonlee/core/ui/base/PageActivity.kt | 8 ++++ .../core/ui/viewmodel}/ProductViewModel.kt | 42 +++++++++++++++++-- .../com/peonlee/explore/ExploreActivity.kt | 10 +++-- .../com/peonlee/product/ProductFragment.kt | 30 ++++++------- .../java/com/peonlee/home/HomeFragment.kt | 17 +++++--- feature/main/build.gradle.kts | 2 + .../java/com/peonlee/main/MainActivity.kt | 17 ++++++-- .../java/com/peonlee/main/MainViewModel.kt | 36 +++++++--------- 8 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 core/ui/src/main/java/com/peonlee/core/ui/base/PageActivity.kt rename {feature/explore/src/main/java/com/peonlee/product => core/ui/src/main/java/com/peonlee/core/ui/viewmodel}/ProductViewModel.kt (72%) diff --git a/core/ui/src/main/java/com/peonlee/core/ui/base/PageActivity.kt b/core/ui/src/main/java/com/peonlee/core/ui/base/PageActivity.kt new file mode 100644 index 00000000..f6905cf8 --- /dev/null +++ b/core/ui/src/main/java/com/peonlee/core/ui/base/PageActivity.kt @@ -0,0 +1,8 @@ +package com.peonlee.core.ui.base + +/** + * page 전환을 할 수 있는 Activity interface + */ +interface PageActivity { + fun moveToEvaluatePage() +} diff --git a/feature/explore/src/main/java/com/peonlee/product/ProductViewModel.kt b/core/ui/src/main/java/com/peonlee/core/ui/viewmodel/ProductViewModel.kt similarity index 72% rename from feature/explore/src/main/java/com/peonlee/product/ProductViewModel.kt rename to core/ui/src/main/java/com/peonlee/core/ui/viewmodel/ProductViewModel.kt index 2e45519c..31d5a8a7 100644 --- a/feature/explore/src/main/java/com/peonlee/product/ProductViewModel.kt +++ b/core/ui/src/main/java/com/peonlee/core/ui/viewmodel/ProductViewModel.kt @@ -1,6 +1,7 @@ -package com.peonlee.product +package com.peonlee.core.ui.viewmodel import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn @@ -65,8 +66,15 @@ class ProductViewModel @Inject constructor( } // 정렬 타입 변경 - fun setProductSortType(sortType: SortType) { - _productSearchCondition.value = _productSearchCondition.value.copy(sortedBy = sortType) + fun setProductSortType(sortType: SortType, isReset: Boolean = false) { + _productSearchCondition.value = if (isReset) _productSearchCondition.value.copy( + keyword = "", + sortedBy = sortType, + price = null, + stores = null, + events = null, + categories = null + ) else _productSearchCondition.value.copy(sortedBy = sortType) } // 가격 필터 선택 @@ -74,6 +82,23 @@ class ProductViewModel @Inject constructor( _productSearchCondition.value = _productSearchCondition.value.copy(price = priceFilter) } + // 편의점 변경 + fun setStoreType(storeType: StoreType, isReset: Boolean = false) { + _productSearchCondition.value = if (isReset) _productSearchCondition.value.copy( + keyword = "", + sortedBy = SortType.RECENT, + price = null, + stores = listOf(storeType), + events = null, + categories = null + ) else _productSearchCondition.value.copy(stores = listOf(storeType)) + } + + // 검색 키워드 변경 + fun setKeyword(keyword: String) { + _productSearchCondition.value = _productSearchCondition.value.copy(keyword = keyword) + } + // 이벤트 선택 fun setEventFilter(stores: List, events: List) { _productSearchCondition.value = _productSearchCondition.value.copy( @@ -100,4 +125,15 @@ class ProductViewModel @Inject constructor( fun setProductSearchCondition(newProductSearchCondition: ProductSearchConditionUiModel) { _productSearchCondition.value = newProductSearchCondition } + + class ProductViewModelFactory( + private val repository: ProductRepository + ) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(ProductViewModel::class.java)) { + return ProductViewModel(repository) as T + } + throw IllegalArgumentException("unKnown ViewModel class") + } + } } diff --git a/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt b/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt index b9d876e9..663e1aef 100644 --- a/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt +++ b/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt @@ -7,20 +7,22 @@ import androidx.activity.viewModels import androidx.core.view.isVisible import androidx.core.widget.addTextChangedListener import com.peonlee.core.ui.base.BaseActivity -import com.peonlee.core.ui.base.ProductSearchableViewModel import com.peonlee.core.ui.extensions.hideKeyboard import com.peonlee.core.ui.extensions.trim +import com.peonlee.core.ui.viewmodel.ProductViewModel import com.peonlee.explore.databinding.ActivityExploreActivityBinding import com.peonlee.product.ProductFragment import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class ExploreActivity : BaseActivity() { - private val exploreViewModel: ProductSearchableViewModel by viewModels { ExploreViewModel.ExploreViewModelFactory() } + private val productViewModel: ProductViewModel by viewModels() + + // private val exploreViewModel: ProductSearchableViewModel by viewModels { ExploreViewModel.ExploreViewModelFactory() } override fun bindingFactory(): ActivityExploreActivityBinding = ActivityExploreActivityBinding.inflate(layoutInflater) override fun initViews() { - println(exploreViewModel) +// println(exploreViewModel) attachProductFragment() } @@ -47,7 +49,7 @@ class ExploreActivity : BaseActivity() { private fun searchResult() { binding.apply { layoutSearchProduct.isVisible = true - (exploreViewModel as? ExploreViewModel)?.setKeyword(etExploreBar.trim()) + productViewModel.setKeyword(etExploreBar.trim()) etExploreBar.clearFocus() etExploreBar.hideKeyboard() } diff --git a/feature/explore/src/main/java/com/peonlee/product/ProductFragment.kt b/feature/explore/src/main/java/com/peonlee/product/ProductFragment.kt index c86a5382..cf85c1a0 100644 --- a/feature/explore/src/main/java/com/peonlee/product/ProductFragment.kt +++ b/feature/explore/src/main/java/com/peonlee/product/ProductFragment.kt @@ -7,18 +7,15 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels -import androidx.fragment.app.viewModels -import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import com.google.android.material.tabs.TabLayout import com.peonlee.core.ui.Navigator import com.peonlee.core.ui.adapter.decoration.ContentPaddingDecoration import com.peonlee.core.ui.base.BaseBottomSheetFragment import com.peonlee.core.ui.base.BaseFragment -import com.peonlee.core.ui.base.ProductSearchableViewModel +import com.peonlee.core.ui.viewmodel.ProductViewModel import com.peonlee.model.product.ProductSearchConditionUiModel import com.peonlee.model.type.SortType import com.peonlee.model.type.toRangeString @@ -34,7 +31,6 @@ import com.peonlee.product.ui.PriceFilterBottomSheetFragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch import javax.inject.Inject @AndroidEntryPoint @@ -42,8 +38,7 @@ class ProductFragment : BaseFragment() { @Inject lateinit var navigator: Navigator - private val exploreViewModel: ProductSearchableViewModel by activityViewModels() - private val productViewModel: ProductViewModel by viewModels() + private val productViewModel: ProductViewModel by activityViewModels() private var currentBottomSheet: BaseBottomSheetFragment? = null private val priceFilter by lazy { @@ -69,7 +64,7 @@ class ProductFragment : BaseFragment() { } override fun initViews() = with(binding) { - observeKeyword() +// observeKeyword() SortType.values().forEach { tabProductSort.addTab( @@ -177,16 +172,15 @@ class ProductFragment : BaseFragment() { ?.show(childFragmentManager, "Filter") } - private fun observeKeyword() { - println(exploreViewModel) - viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - exploreViewModel.productSearchCondition.collect { - productViewModel.setProductSearchCondition(it) - } - } - } - } +// private fun observeKeyword() { +// viewLifecycleOwner.lifecycleScope.launch { +// viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { +// exploreViewModel.productSearchCondition.collect { +// productViewModel.setProductSearchCondition(it) +// } +// } +// } +// } companion object { fun getInstance(): ProductFragment = ProductFragment() diff --git a/feature/home/src/main/java/com/peonlee/home/HomeFragment.kt b/feature/home/src/main/java/com/peonlee/home/HomeFragment.kt index e8759b81..ee3ae22e 100644 --- a/feature/home/src/main/java/com/peonlee/home/HomeFragment.kt +++ b/feature/home/src/main/java/com/peonlee/home/HomeFragment.kt @@ -8,7 +8,8 @@ import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import com.peonlee.core.ui.Navigator import com.peonlee.core.ui.base.BaseFragment -import com.peonlee.core.ui.base.ProductSearchableViewModel +import com.peonlee.core.ui.base.PageActivity +import com.peonlee.core.ui.viewmodel.ProductViewModel import com.peonlee.home.adapter.HomeAdapter import com.peonlee.home.databinding.FragmentHomeBinding import dagger.hilt.android.AndroidEntryPoint @@ -20,15 +21,20 @@ import javax.inject.Inject class HomeFragment : BaseFragment() { @Inject lateinit var navigator: Navigator - + private val productSearchableViewModel: ProductViewModel by activityViewModels() private val homeViewModel: HomeViewModel by viewModels() - private val productSearchableViewModel: ProductSearchableViewModel by activityViewModels() private val homeAdapter by lazy { HomeAdapter( navigator = navigator, - moveToConditionExplore = productSearchableViewModel::changeSortType, - moveToStoreExplore = productSearchableViewModel::changeStoreType + moveToConditionExplore = { + (requireActivity() as? PageActivity)?.moveToEvaluatePage() + productSearchableViewModel.setProductSortType(it, true) + }, + moveToStoreExplore = { + (requireActivity() as? PageActivity)?.moveToEvaluatePage() + productSearchableViewModel.setStoreType(it, true) + } ) } @@ -38,6 +44,7 @@ class HomeFragment : BaseFragment() { override fun initViews() { binding.rvHome.adapter = homeAdapter +// productSearchableViewModel binding.btnSearch.setOnClickListener { navigator.navigateToSearch(requireContext()) } diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index 20a136b6..be5f6320 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -14,6 +14,8 @@ dependencies { implementation(project(":feature:evaluate")) implementation(project(":core:model")) + implementation(project(":core:data")) + implementation(libs.google.material) implementation(libs.bundles.fragment) } diff --git a/feature/main/src/main/java/com/peonlee/main/MainActivity.kt b/feature/main/src/main/java/com/peonlee/main/MainActivity.kt index 232fab52..eae5782f 100644 --- a/feature/main/src/main/java/com/peonlee/main/MainActivity.kt +++ b/feature/main/src/main/java/com/peonlee/main/MainActivity.kt @@ -6,17 +6,24 @@ import androidx.activity.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import com.peonlee.core.ui.base.BaseActivity -import com.peonlee.core.ui.base.ProductSearchableViewModel +import com.peonlee.core.ui.base.PageActivity +import com.peonlee.core.ui.viewmodel.ProductViewModel +import com.peonlee.data.product.ProductRepository import com.peonlee.main.databinding.ActivityMainBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import javax.inject.Inject @AndroidEntryPoint -class MainActivity : BaseActivity() { - private val mainViewModel: ProductSearchableViewModel by viewModels { MainViewModel.MainViewModelFactory() } +class MainActivity : BaseActivity(), PageActivity { + @Inject + lateinit var productRepository: ProductRepository + private val productViewModel: ProductViewModel by viewModels { ProductViewModel.ProductViewModelFactory(productRepository) } + private val mainViewModel: MainViewModel by viewModels { MainViewModel.MainViewModelFactory() } override fun initViews() { + productViewModel binding.bottomNav.setOnItemSelectedListener { (mainViewModel as? MainViewModel)?.changeSelectedNav(it.itemId) true @@ -52,6 +59,10 @@ class MainActivity : BaseActivity() { super.onBackPressed() } + override fun moveToEvaluatePage() { + mainViewModel.changeSelectedNav(R.id.navExplore) + } + companion object { fun startActivity(context: Context) { context.startActivity( diff --git a/feature/main/src/main/java/com/peonlee/main/MainViewModel.kt b/feature/main/src/main/java/com/peonlee/main/MainViewModel.kt index c58123c8..c809d32a 100644 --- a/feature/main/src/main/java/com/peonlee/main/MainViewModel.kt +++ b/feature/main/src/main/java/com/peonlee/main/MainViewModel.kt @@ -2,10 +2,6 @@ package com.peonlee.main import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.peonlee.core.ui.base.ProductSearchableViewModel -import com.peonlee.model.product.ProductSearchConditionUiModel -import com.peonlee.model.type.SortType -import com.peonlee.model.type.StoreType import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -13,7 +9,7 @@ import kotlinx.coroutines.flow.asStateFlow import javax.inject.Inject @HiltViewModel -class MainViewModel @Inject constructor() : ProductSearchableViewModel() { +class MainViewModel @Inject constructor() : ViewModel() { private val _selectedNav = MutableStateFlow(R.id.navHome) val selectedNav: StateFlow = _selectedNav.asStateFlow() @@ -24,21 +20,21 @@ class MainViewModel @Inject constructor() : ProductSearchableViewModel() { _selectedNav.value = navId } - /** - * 정렬 키워드 변경 - */ - override fun changeSortType(sortType: SortType) { - _productSearchCondition.value = ProductSearchConditionUiModel(sortedBy = sortType) - _selectedNav.value = R.id.navExplore - } - - /** - * 편의점의 행사 상품 변경 - */ - override fun changeStoreType(storeType: StoreType) { - _productSearchCondition.value = ProductSearchConditionUiModel(stores = listOf(storeType)) - _selectedNav.value = R.id.navExplore - } +// /** +// * 정렬 키워드 변경 +// */ +// override fun changeSortType(sortType: SortType) { +// _productSearchCondition.value = ProductSearchConditionUiModel(sortedBy = sortType) +// _selectedNav.value = R.id.navExplore +// } +// +// /** +// * 편의점의 행사 상품 변경 +// */ +// override fun changeStoreType(storeType: StoreType) { +// _productSearchCondition.value = ProductSearchConditionUiModel(stores = listOf(storeType)) +// _selectedNav.value = R.id.navExplore +// } class MainViewModelFactory : ViewModelProvider.Factory { override fun create(modelClass: Class): T { From 6803f89fce21be489dcf1b44b810354e521f0405 Mon Sep 17 00:00:00 2001 From: aurora32s Date: Sun, 8 Oct 2023 16:40:47 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[FIX]=20#117=20-=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/peonlee/explore/ExploreActivity.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt b/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt index 663e1aef..30d08928 100644 --- a/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt +++ b/feature/explore/src/main/java/com/peonlee/explore/ExploreActivity.kt @@ -10,19 +10,22 @@ import com.peonlee.core.ui.base.BaseActivity import com.peonlee.core.ui.extensions.hideKeyboard import com.peonlee.core.ui.extensions.trim import com.peonlee.core.ui.viewmodel.ProductViewModel +import com.peonlee.data.product.ProductRepository import com.peonlee.explore.databinding.ActivityExploreActivityBinding import com.peonlee.product.ProductFragment import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject @AndroidEntryPoint class ExploreActivity : BaseActivity() { - private val productViewModel: ProductViewModel by viewModels() + @Inject + lateinit var productRepository: ProductRepository + private val productViewModel: ProductViewModel by viewModels { ProductViewModel.ProductViewModelFactory(productRepository) } - // private val exploreViewModel: ProductSearchableViewModel by viewModels { ExploreViewModel.ExploreViewModelFactory() } override fun bindingFactory(): ActivityExploreActivityBinding = ActivityExploreActivityBinding.inflate(layoutInflater) override fun initViews() { -// println(exploreViewModel) + productViewModel attachProductFragment() }