Skip to content

Commit

Permalink
#6 feat/홈 : 홈 화면 상단 영역 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
HayleyKim0716 committed Aug 2, 2022
1 parent b8b1421 commit 517f302
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -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
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
Expand Down
59 changes: 49 additions & 10 deletions app/src/main/java/com/ftw/hometerview/ui/main/home/HomeFragment.kt
Original file line number Diff line number Diff line change
@@ -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<FragmentHomeBinding?>(
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()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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
}
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<User> = MutableStateFlow(User.NONE)
val user: StateFlow<User> = _user.asStateFlow()

private val _reviews: MutableStateFlow<List<LocationReview>> = MutableStateFlow(emptyList())
val reviews: StateFlow<List<LocationReview>> = _reviews.asStateFlow()

private val _state: MutableStateFlow<State> = MutableStateFlow(State.None)
val state: StateFlow<State> = _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
}
}
}
}
107 changes: 98 additions & 9 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>

<TextView
<data>
<variable
name="viewModel"
type="com.ftw.hometerview.ui.main.home.HomeViewModel"
/>
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="HomeFragment"
/>
>

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
app:layout_constraintTop_toTopOf="parent"
>

<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/blue_300"
app:layout_scrollFlags="scroll|enterAlways"
>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<TextView
android:id="@+id/company_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_size_30"
android:layout_marginHorizontal="@dimen/dp_size_14"
android:text="@{viewModel.user.company.name}"
android:fontFamily="@font/pretendard_medium"
android:textColor="@color/white"
android:textSize="@dimen/sp_size_24"
app:layout_constraintTop_toTopOf="parent"
/>

<TextView
android:id="@+id/company_guide_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/dp_size_14"
android:text="@string/home_title"
android:fontFamily="@font/pretendard_regular"
android:textColor="@color/white"
android:textSize="@dimen/sp_size_24"
app:layout_constraintTop_toBottomOf="@id/company_text_view"
/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_size_8"
android:layout_marginBottom="@dimen/dp_size_35"
android:layout_marginHorizontal="@dimen/dp_size_14"
android:text="@{@string/home_description(viewModel.user.company.location)}"
android:fontFamily="@font/pretendard_regular"
android:textColor="@color/white"
android:textSize="@dimen/sp_size_14"
app:layout_constraintTop_toBottomOf="@id/company_guide_text_view"
app:layout_constraintBottom_toBottomOf="parent"
/>

</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>

<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_size_20"
android:layout_marginHorizontal="@dimen/sp_size_14"
app:tabMode="scrollable"
app:tabTextAppearance="@style/HomeTabLayout"
app:tabIndicatorColor="@color/gray_900"
app:tabIndicatorHeight="@dimen/dp_size_2"
app:tabTextColor="@color/gray_500"
app:tabSelectedTextColor="@color/gray_900"
/>
</com.google.android.material.appbar.AppBarLayout>

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/app_bar_layout"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>
</layout>
5 changes: 5 additions & 0 deletions app/src/main/res/values/dimen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<resources>

<!-- Text size -->
<dimen name="sp_size_24">24sp</dimen>
<dimen name="sp_size_14">14sp</dimen>

<dimen name="guide_text_size">20sp</dimen>

<dimen name="title_text_size">36sp</dimen>
Expand All @@ -24,7 +27,9 @@
<dimen name="dp_size_16">16dp</dimen>
<dimen name="dp_size_20">20dp</dimen>
<dimen name="dp_size_24">24dp</dimen>
<dimen name="dp_size_30">30dp</dimen>
<dimen name="dp_size_32">32dp</dimen>
<dimen name="dp_size_35">35dp</dimen>
<dimen name="dp_size_400">400dp</dimen>

<!-- margin size -->
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<string name="main_bottom_navigation_menu_heart">찜하기</string>
<string name="main_bottom_navigation_menu_user">MY</string>

<string name="home_title">통근러에게 추천하는 동네</string>
<string name="home_description">%s 직장인들이 많이 사는 동네의 리뷰입니다</string>

<string name="get_token_error">저장된 토큰이 없습니다.</string>
<string name="guide_text1">나랑 같은 지역으로 출근하는 사람들은 어디에 살고있을까?</string>
<string name="guide_text2">집터뷰는 같은 지하철역으로 출근하는 사람들이 많이 사는 지역을 추천해줘요!</string>
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="HomeTabLayout" parent="Widget.Material3.TabLayout">
<item name="fontFamily">@font/pretendard_medium</item>
<item name="android:textSize">@dimen/sp_size_14</item>
</style>

</resources>

0 comments on commit 517f302

Please sign in to comment.