From 517f30241494d67b69c9276f3a3c30e47f555f10 Mon Sep 17 00:00:00 2001 From: HayleyKim0716 Date: Tue, 2 Aug 2022 23:12:41 +0900 Subject: [PATCH] =?UTF-8?q?#6=20feat/=ED=99=88=20:=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=83=81=EB=8B=A8=20=EC=98=81=EC=97=AD=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../di/ui/MainFragmentViewModelModule.kt | 30 +++++ ... => BottomNavigationViewBindingAdapter.kt} | 0 .../ftw/hometerview/ui/main/MainActivity.kt | 2 +- .../hometerview/ui/main/home/HomeFragment.kt | 59 ++++++++-- .../hometerview/ui/main/home/HomeViewModel.kt | 56 ++++++++- app/src/main/res/layout/fragment_home.xml | 107 ++++++++++++++++-- app/src/main/res/values/dimen.xml | 5 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 8 ++ 9 files changed, 246 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/com/ftw/hometerview/di/ui/MainFragmentViewModelModule.kt rename app/src/main/java/com/ftw/hometerview/ui/bindingadapter/{BottomNavigationViewAdapter.kt => BottomNavigationViewBindingAdapter.kt} (100%) create mode 100644 app/src/main/res/values/styles.xml diff --git a/app/src/main/java/com/ftw/hometerview/di/ui/MainFragmentViewModelModule.kt b/app/src/main/java/com/ftw/hometerview/di/ui/MainFragmentViewModelModule.kt new file mode 100644 index 0000000..c5c0047 --- /dev/null +++ b/app/src/main/java/com/ftw/hometerview/di/ui/MainFragmentViewModelModule.kt @@ -0,0 +1,30 @@ +package com.ftw.hometerview.di.ui + +import com.ftw.domain.usecase.review.GetLocaionReviewsUseCase +import com.ftw.domain.usecase.user.GetCachedUserUseCase +import com.ftw.hometerview.dispatcher.Dispatcher +import com.ftw.hometerview.ui.main.home.HomeViewModel +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.FragmentComponent +import dagger.hilt.android.scopes.FragmentScoped + +@Module +@InstallIn(FragmentComponent::class) +class MainFragmentViewModelModule { + + @Provides + @FragmentScoped + fun provideHomeViewModel( + dispatcher: Dispatcher, + getCachedUserUseCase: GetCachedUserUseCase, + getLocationReviewsUseCase: GetLocaionReviewsUseCase + ): HomeViewModel { + return HomeViewModel( + dispatcher, + getCachedUserUseCase, + getLocationReviewsUseCase + ) + } +} diff --git a/app/src/main/java/com/ftw/hometerview/ui/bindingadapter/BottomNavigationViewAdapter.kt b/app/src/main/java/com/ftw/hometerview/ui/bindingadapter/BottomNavigationViewBindingAdapter.kt similarity index 100% rename from app/src/main/java/com/ftw/hometerview/ui/bindingadapter/BottomNavigationViewAdapter.kt rename to app/src/main/java/com/ftw/hometerview/ui/bindingadapter/BottomNavigationViewBindingAdapter.kt diff --git a/app/src/main/java/com/ftw/hometerview/ui/main/MainActivity.kt b/app/src/main/java/com/ftw/hometerview/ui/main/MainActivity.kt index 5bf1333..338ad8e 100644 --- a/app/src/main/java/com/ftw/hometerview/ui/main/MainActivity.kt +++ b/app/src/main/java/com/ftw/hometerview/ui/main/MainActivity.kt @@ -29,7 +29,7 @@ class MainActivity : AppCompatActivity() { @Inject lateinit var viewModel: MainViewModel - private val homeFragment by lazy { HomeFragment() } + private val homeFragment by lazy { HomeFragment.newInstance() } private val mapFragment by lazy { MapFragment() } private val favoriteFragment by lazy { FavoriteFragment() } private val myPageFragment by lazy { MyPageFragment() } diff --git a/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeFragment.kt b/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeFragment.kt index 119ca6b..ffd67e5 100644 --- a/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeFragment.kt +++ b/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeFragment.kt @@ -1,32 +1,71 @@ package com.ftw.hometerview.ui.main.home -import androidx.lifecycle.ViewModelProvider import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.ftw.hometerview.R +import com.ftw.hometerview.databinding.FragmentHomeBinding +import com.google.android.material.tabs.TabLayoutMediator +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import javax.inject.Inject +@AndroidEntryPoint class HomeFragment : Fragment() { companion object { fun newInstance() = HomeFragment() } - private lateinit var viewModel: HomeViewModel + private var _binding: FragmentHomeBinding? = null + private val binding get() = _binding!! + + @Inject + lateinit var viewModel: HomeViewModel override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.fragment_home, container, false) + ): View { + _binding = DataBindingUtil.inflate( + inflater, + R.layout.fragment_home, + container, + false + ).apply { + viewModel = this@HomeFragment.viewModel + } + return binding.root } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProvider(this).get(HomeViewModel::class.java) - // TODO: Use the ViewModel + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + observe() } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + private fun observe() { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.reviews.collect { reviews -> + val activity = activity ?: return@collect + val locations = reviews.map { it.location } + binding.viewPager.adapter = HomeViewPagerAdapter(activity, locations) + TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position -> + tab.text = locations[position] + }.attach() + } + } + } + } } diff --git a/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeViewModel.kt b/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeViewModel.kt index 6681d81..3b973ae 100644 --- a/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeViewModel.kt +++ b/app/src/main/java/com/ftw/hometerview/ui/main/home/HomeViewModel.kt @@ -1,7 +1,55 @@ package com.ftw.hometerview.ui.main.home -import androidx.lifecycle.ViewModel +import com.ftw.domain.entity.Company +import com.ftw.domain.entity.LocationReview +import com.ftw.domain.entity.User +import com.ftw.domain.usecase.review.GetLocaionReviewsUseCase +import com.ftw.domain.usecase.user.GetCachedUserUseCase +import com.ftw.hometerview.dispatcher.Dispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.launch -class HomeViewModel : ViewModel() { - // TODO: Implement the ViewModel -} \ No newline at end of file +class HomeViewModel( + private val dispatcher: Dispatcher, + private val getCachedUserUseCase: GetCachedUserUseCase, + private val getLocationReviewsUseCase: GetLocaionReviewsUseCase +) { + sealed class State { + object None : State() + class Error(val message: String) : State() + } + + private val _user: MutableStateFlow = MutableStateFlow(User.NONE) + val user: StateFlow = _user.asStateFlow() + + private val _reviews: MutableStateFlow> = MutableStateFlow(emptyList()) + val reviews: StateFlow> = _reviews.asStateFlow() + + private val _state: MutableStateFlow = MutableStateFlow(State.None) + val state: StateFlow = _state.asStateFlow() + + init { + CoroutineScope(dispatcher.ui()).launch { + flow { + emit(getCachedUserUseCase()) + } + .catch { emit(User(Company.NONE)) } + .collect { + _user.value = it + } + + flow { + emit(getLocationReviewsUseCase(user.value.company?.location ?: "역삼역")) + } + .catch { exception -> _state.value = State.Error(exception.message ?: "") } + .collect { + _reviews.value = it + } + } + } +} diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 60d48b8..f4be161 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,15 +1,104 @@ - - + + + + + > + + + + + + + + + + + + + + + + + + + + + - + diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index 59cc53c..429ac76 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -2,6 +2,9 @@ + 24sp + 14sp + 20sp 36sp @@ -24,7 +27,9 @@ 16dp 20dp 24dp + 30dp 32dp + 35dp 400dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f72ec89..aa9cacc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,9 @@ 찜하기 MY + 통근러에게 추천하는 동네 + %s 직장인들이 많이 사는 동네의 리뷰입니다 + 저장된 토큰이 없습니다. 나랑 같은 지역으로 출근하는 사람들은 어디에 살고있을까? 집터뷰는 같은 지하철역으로 출근하는 사람들이 많이 사는 지역을 추천해줘요! diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d77112b --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + +