diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ae388c2..cb865f6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,8 +4,6 @@ diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2460585..52847e4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,6 +3,7 @@ plugins { id("org.jetbrains.kotlin.android") id("kotlin-kapt") id("com.google.dagger.hilt.android") + id ("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } android { @@ -77,7 +78,7 @@ dependencies { implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") implementation ("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") - implementation ("androidx.collection:collection-ktx:1.3.0") + implementation ("androidx.collection:collection-ktx:1.4.0") implementation ("androidx.navigation:navigation-runtime-ktx:2.7.6") implementation ("androidx.navigation:navigation-fragment-ktx:2.7.6") implementation ("androidx.navigation:navigation-ui-ktx:2.7.6") @@ -86,10 +87,12 @@ dependencies { implementation ("com.github.bumptech.glide:glide:4.11.0") annotationProcessor ("com.github.bumptech.glide:compiler:4.11.0") - implementation ("androidx.camera:camera-core:1.4.0-alpha03") - implementation ("androidx.camera:camera-camera2:1.4.0-alpha03") - implementation ("androidx.camera:camera-lifecycle:1.4.0-alpha03") - implementation ("androidx.camera:camera-view:1.4.0-alpha03") + implementation ("androidx.camera:camera-core:1.4.0-alpha04") + implementation ("androidx.camera:camera-camera2:1.4.0-alpha04") + implementation ("androidx.camera:camera-lifecycle:1.4.0-alpha04") + implementation ("androidx.camera:camera-view:1.4.0-alpha04") implementation ("com.journeyapps:zxing-android-embedded:4.3.0") + + implementation ("com.google.android.gms:play-services-maps:18.2.0") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ba9c94f..7d7cad4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,11 @@ android:theme="@style/Theme.Coumo" android:hardwareAccelerated="true" tools:targetApi="31"> + + + @@ -26,6 +31,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/data/remote/model/request/RequestLocationModel.kt b/app/src/main/java/com/umc/coumo/data/remote/model/request/RequestLocationModel.kt new file mode 100644 index 0000000..b591ded --- /dev/null +++ b/app/src/main/java/com/umc/coumo/data/remote/model/request/RequestLocationModel.kt @@ -0,0 +1,6 @@ +package com.umc.coumo.data.remote.model.request + +data class RequestLocationModel( + val longitude: Double = 127.028194, + val latitude: Double = 37.498085 +) diff --git a/app/src/main/java/com/umc/coumo/data/remote/model/response/ResponsePopularStoreModel.kt b/app/src/main/java/com/umc/coumo/data/remote/model/response/ResponsePopularStoreModel.kt new file mode 100644 index 0000000..7a47a9c --- /dev/null +++ b/app/src/main/java/com/umc/coumo/data/remote/model/response/ResponsePopularStoreModel.kt @@ -0,0 +1,9 @@ +package com.umc.coumo.data.remote.model.response + +data class ResponsePopularStoreModel( + val storeId: Int, + val name: String, + val location: String, + val description: String, + val storeImage: String +) \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/model/DummyModel.kt b/app/src/main/java/com/umc/coumo/domain/model/DummyModel.kt deleted file mode 100644 index 6e5a656..0000000 --- a/app/src/main/java/com/umc/coumo/domain/model/DummyModel.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.umc.coumo.domain.model - -data class DummyModel( - val dummy: String -) diff --git a/app/src/main/java/com/umc/coumo/domain/model/ImageViewPagerModel.kt b/app/src/main/java/com/umc/coumo/domain/model/ImageViewPagerModel.kt new file mode 100644 index 0000000..c1e424e --- /dev/null +++ b/app/src/main/java/com/umc/coumo/domain/model/ImageViewPagerModel.kt @@ -0,0 +1,8 @@ +package com.umc.coumo.domain.model + +import android.net.Uri + +data class ImageViewPagerModel( + val image: Uri, +) { +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/model/MenuModel.kt b/app/src/main/java/com/umc/coumo/domain/model/MenuModel.kt index 8051a66..ebbf37b 100644 --- a/app/src/main/java/com/umc/coumo/domain/model/MenuModel.kt +++ b/app/src/main/java/com/umc/coumo/domain/model/MenuModel.kt @@ -3,9 +3,8 @@ package com.umc.coumo.domain.model import android.net.Uri data class MenuModel( - val id: Int, val name: String, - val content: String, + val description: String, val image: Uri? = null, val isNew: Boolean = false ) \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/model/StoreInfoItemModel.kt b/app/src/main/java/com/umc/coumo/domain/model/StoreInfoItemModel.kt new file mode 100644 index 0000000..28a50c6 --- /dev/null +++ b/app/src/main/java/com/umc/coumo/domain/model/StoreInfoItemModel.kt @@ -0,0 +1,11 @@ +package com.umc.coumo.domain.model + +import android.net.Uri + +data class StoreInfoItemModel( + val id : Int, + val image: Uri? = null, + val name: String, + val address: String, + val description: String, +) diff --git a/app/src/main/java/com/umc/coumo/domain/model/StoreInfoModel.kt b/app/src/main/java/com/umc/coumo/domain/model/StoreInfoModel.kt index f683792..2868f8d 100644 --- a/app/src/main/java/com/umc/coumo/domain/model/StoreInfoModel.kt +++ b/app/src/main/java/com/umc/coumo/domain/model/StoreInfoModel.kt @@ -3,9 +3,13 @@ package com.umc.coumo.domain.model import android.net.Uri data class StoreInfoModel( - val id : Int, - val image: Uri? = null, val name: String, - val address: String, - val content: String, -) + val description: String, + val location: String, + val longitude: Double, + val latitude: Double, + val image: List?, + val coupon: CouponModel, + val menuList: List, +) { +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/type/CategoryType.kt b/app/src/main/java/com/umc/coumo/domain/type/CategoryType.kt new file mode 100644 index 0000000..1ed5ff5 --- /dev/null +++ b/app/src/main/java/com/umc/coumo/domain/type/CategoryType.kt @@ -0,0 +1,10 @@ +package com.umc.coumo.domain.type + +enum class CategoryType(val title: String) { + CAFE("카페/디저트"), + RETAIL1("리테일"), + FOOD("요식업"), + RETAIL2("리테일"), + BEAUTY("뷰티/살롱"), + CLASS("학원/클래스"), +} diff --git a/app/src/main/java/com/umc/coumo/domain/type/Status.kt b/app/src/main/java/com/umc/coumo/domain/type/Status.kt new file mode 100644 index 0000000..810ccb0 --- /dev/null +++ b/app/src/main/java/com/umc/coumo/domain/type/Status.kt @@ -0,0 +1,7 @@ +package com.umc.coumo.domain.type + +enum class Status { + SUCCESS, + ERROR, + LOADING +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/viewmodel/HomeViewModel.kt b/app/src/main/java/com/umc/coumo/domain/viewmodel/HomeViewModel.kt index 3d65db3..a974ff5 100644 --- a/app/src/main/java/com/umc/coumo/domain/viewmodel/HomeViewModel.kt +++ b/app/src/main/java/com/umc/coumo/domain/viewmodel/HomeViewModel.kt @@ -1,9 +1,14 @@ package com.umc.coumo.domain.viewmodel +import android.net.Uri import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import com.umc.coumo.domain.model.CouponModel import com.umc.coumo.domain.model.MenuModel +import com.umc.coumo.domain.model.StoreCouponCountModel +import com.umc.coumo.domain.model.StoreInfoModel +import com.umc.coumo.domain.type.CategoryType import com.umc.coumo.domain.type.DetailTabType import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -14,25 +19,53 @@ class HomeViewModel @Inject constructor(): ViewModel() { private val _currentTab = MutableLiveData(DetailTabType.INFO) val currentTab: LiveData get() = _currentTab - private val _menuList = MutableLiveData>() - val menuList: LiveData> get() = _menuList + private val _storeData = MutableLiveData() + val storeData: LiveData get() = _storeData + + //카테고리 + private val _category = MutableLiveData(CategoryType.CAFE) + val category: LiveData get() = _category + + //근처 매장 리스트 + private val _nearStoreList = MutableLiveData>() + val nearStoreList: LiveData> get() = _nearStoreList + + //인기 매장 리스트 + private val _popularStoreList = MutableLiveData>() + val popularStoreList: LiveData> get() = _popularStoreList - init { - testData() - } fun changeTab(tab: DetailTabType) { _currentTab.value = tab } + fun selectCategory(category: CategoryType) { + _category.value = category + //리스트 요청 + } + + fun loadStoreData() { + // TODO( API 에서 데이터 가져오기 ) + testData() + } + private fun testData() { - val list = listOf( - MenuModel(id = 0, name = "아이스 바닐라 라떼", content = "Tall: 4,800\nGrande: 6,800\nTrenta: 6,800"), - MenuModel(id = 1, name = "아이스 바닐라 라떼2", content = "Tall: 4,800\nGrande: 6,800\nTrenta: 6,800", isNew = true), - MenuModel(id = 2, name = "아이스 바닐라 라떼3", content = "Tall: 4,800\nGrande: 6,800\nTrenta: 6,800",), - MenuModel(id = 3, name = "아이스 바닐라 라떼4", content = "Tall: 4,800\nGrande: 6,800\nTrenta: 6,800",), - MenuModel(id = 4, name = "아이스 바닐라 라떼5", content = "Tall: 4,800\nGrande: 6,800\nTrenta: 6,800",), + _storeData.value = StoreInfoModel( + name = "앙떼띠 로스터리(강남점)", + description = "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + "아메리카노 2000원 이벤트를 진행 중입니다.", + location = "가게 위치 정보", + longitude = 127.02629637, + latitude = 37.500075, + image = listOf(Uri.parse(""), + ), + coupon = CouponModel("?",1,"1",1,null), + menuList = listOf( + MenuModel("메뉴 이름1","메뉴 정보1"), + MenuModel("메뉴 이름2","메뉴 정보2", isNew = true), + MenuModel("메뉴 이름3","메뉴 정보3"), + MenuModel("메뉴 이름4","메뉴 정보4"), + ) ) - _menuList.value = list } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/domain/viewmodel/MainViewModel.kt b/app/src/main/java/com/umc/coumo/domain/viewmodel/MainViewModel.kt index 099ca80..d931e5f 100644 --- a/app/src/main/java/com/umc/coumo/domain/viewmodel/MainViewModel.kt +++ b/app/src/main/java/com/umc/coumo/domain/viewmodel/MainViewModel.kt @@ -12,6 +12,8 @@ class MainViewModel @Inject constructor(): ViewModel() { private val _currentPageIndex = MutableLiveData(TabType.HOME) val currentPageIndex: LiveData get() = _currentPageIndex + + fun changePageIndex(type: TabType) { _currentPageIndex.value = type } diff --git a/app/src/main/java/com/umc/coumo/presentation/adapter/ImageViewPagerAdapter.kt b/app/src/main/java/com/umc/coumo/presentation/adapter/ImageViewPagerAdapter.kt new file mode 100644 index 0000000..c57c710 --- /dev/null +++ b/app/src/main/java/com/umc/coumo/presentation/adapter/ImageViewPagerAdapter.kt @@ -0,0 +1,40 @@ +package com.umc.coumo.presentation.adapter + +import android.content.Context +import android.net.Uri +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.umc.coumo.databinding.ItemImageViewpagerBinding +import com.umc.coumo.utils.ItemDiffCallback + +class ImageViewPagerAdapter(val context: Context): ListAdapter( + ItemDiffCallback( + onContentsTheSame = {old, new -> old == new}, + onItemsTheSame = {old, new -> old == new} + ) +){ + inner class ItemViewHolder( + private val binding: ItemImageViewpagerBinding + ): RecyclerView.ViewHolder(binding.root) { + fun bind(item: Uri) { + binding.item = item + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val inflater = LayoutInflater.from(parent.context) + return ItemViewHolder(ItemImageViewpagerBinding.inflate(inflater, parent, false)) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val item = getItem(position) + + when (holder) { + is ItemViewHolder -> { + holder.bind(item) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/presentation/adapter/MenuAdapter.kt b/app/src/main/java/com/umc/coumo/presentation/adapter/MenuAdapter.kt index 6b030cc..484605d 100644 --- a/app/src/main/java/com/umc/coumo/presentation/adapter/MenuAdapter.kt +++ b/app/src/main/java/com/umc/coumo/presentation/adapter/MenuAdapter.kt @@ -15,7 +15,7 @@ class MenuAdapter( ): ListAdapter( ItemDiffCallback( onContentsTheSame = {old, new -> old == new}, - onItemsTheSame = {old, new -> old.id == new.id} + onItemsTheSame = {old, new -> old.name == new.name} ) ) { companion object { @@ -49,17 +49,11 @@ companion object { } } - - inner class MenuViewHolder( private val binding: ItemMenuBinding ): RecyclerView.ViewHolder(binding.root) { fun bind(item: MenuModel) { binding.item = item - - itemView.setOnClickListener { - listener?.onItemClick(item.id) - } } } @@ -68,10 +62,6 @@ companion object { ): RecyclerView.ViewHolder(binding.root) { fun bind(item: MenuModel) { binding.item = item - - itemView.setOnClickListener { - listener?.onItemClick(item.id) - } } } diff --git a/app/src/main/java/com/umc/coumo/presentation/adapter/StoreCouponCountAdapter.kt b/app/src/main/java/com/umc/coumo/presentation/adapter/StoreCouponCountAdapter.kt index 3bf926e..1745596 100644 --- a/app/src/main/java/com/umc/coumo/presentation/adapter/StoreCouponCountAdapter.kt +++ b/app/src/main/java/com/umc/coumo/presentation/adapter/StoreCouponCountAdapter.kt @@ -6,9 +6,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.umc.coumo.databinding.ItemStoreCouponCountBinding -import com.umc.coumo.databinding.ItemStoreInfoBinding import com.umc.coumo.domain.model.StoreCouponCountModel -import com.umc.coumo.domain.model.StoreInfoModel import com.umc.coumo.utils.ItemDiffCallback class StoreCouponCountAdapter( diff --git a/app/src/main/java/com/umc/coumo/presentation/adapter/StoreInfoAdapter.kt b/app/src/main/java/com/umc/coumo/presentation/adapter/StoreInfoAdapter.kt index d91fe61..be409a6 100644 --- a/app/src/main/java/com/umc/coumo/presentation/adapter/StoreInfoAdapter.kt +++ b/app/src/main/java/com/umc/coumo/presentation/adapter/StoreInfoAdapter.kt @@ -6,13 +6,13 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.umc.coumo.databinding.ItemStoreInfoBinding -import com.umc.coumo.domain.model.StoreInfoModel +import com.umc.coumo.domain.model.StoreInfoItemModel import com.umc.coumo.utils.ItemDiffCallback class StoreInfoAdapter( -): ListAdapter( - ItemDiffCallback( +): ListAdapter( + ItemDiffCallback( onContentsTheSame = {old, new -> old == new}, onItemsTheSame = {old, new -> old.id == new.id} ) @@ -35,7 +35,7 @@ class StoreInfoAdapter( inner class StoreInfoViewHolder( private val binding: ItemStoreInfoBinding ): RecyclerView.ViewHolder(binding.root) { - fun bind(item: StoreInfoModel) { + fun bind(item: StoreInfoItemModel) { binding.item = item itemView.setOnClickListener { diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityAllFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityAllFragment.kt index 4f9448b..dc24798 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityAllFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityAllFragment.kt @@ -6,8 +6,7 @@ import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.LinearLayoutManager import com.umc.coumo.R import com.umc.coumo.databinding.FragmentCommunityAllBinding -import com.umc.coumo.databinding.FragmentCommunityBinding -import com.umc.coumo.domain.model.StoreInfoModel +import com.umc.coumo.domain.model.StoreInfoItemModel import com.umc.coumo.domain.viewmodel.CommunityViewModel import com.umc.coumo.presentation.adapter.StoreInfoAdapter import com.umc.coumo.utils.ItemSpacingDecoration @@ -36,14 +35,14 @@ class CommunityAllFragment: BindingFragment(R.layou layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false) } - val list = listOf( - StoreInfoModel(1, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + val list = listOf( + StoreInfoItemModel(1, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(2, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(2, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(3, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(3, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(4, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(4, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), ) diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFilterFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFilterFragment.kt index fb04e15..3a94964 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFilterFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFilterFragment.kt @@ -7,11 +7,8 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.umc.coumo.R import com.umc.coumo.databinding.FragmentCommunityFilterBinding import com.umc.coumo.domain.model.StoreCouponCountModel -import com.umc.coumo.domain.model.StoreInfoModel import com.umc.coumo.domain.viewmodel.CommunityViewModel import com.umc.coumo.presentation.adapter.StoreCouponCountAdapter -import com.umc.coumo.presentation.adapter.StoreInfoAdapter -import com.umc.coumo.utils.ItemSpacingDecoration import com.umc.coumo.utils.binding.BindingFragment class CommunityFilterFragment: BindingFragment(R.layout.fragment_community_filter) { diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFragment.kt index 221db15..4c88cf0 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/CommunityFragment.kt @@ -1,18 +1,14 @@ package com.umc.coumo.presentation.fragment import android.os.Bundle -import android.util.Log import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.LinearLayoutManager import com.umc.coumo.R import com.umc.coumo.databinding.FragmentCommunityBinding -import com.umc.coumo.domain.model.StoreInfoModel import com.umc.coumo.domain.type.CommunityTabType import com.umc.coumo.domain.viewmodel.CommunityViewModel -import com.umc.coumo.presentation.adapter.StoreInfoAdapter import com.umc.coumo.utils.binding.BindingFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeDetailFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeDetailFragment.kt index a4864c4..eb201ec 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeDetailFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeDetailFragment.kt @@ -3,14 +3,19 @@ package com.umc.coumo.presentation.fragment import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController import com.umc.coumo.R import com.umc.coumo.databinding.FragmentHomeDetailBinding import com.umc.coumo.domain.type.DetailTabType import com.umc.coumo.domain.viewmodel.HomeViewModel import com.umc.coumo.presentation.adapter.HomeDetailViewPagerAdapter -import com.umc.coumo.utils.binding.BindingFragmentNoneBackPress +import com.umc.coumo.presentation.adapter.ImageViewPagerAdapter +import com.umc.coumo.utils.binding.BindingFragment +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch -class HomeDetailFragment: BindingFragmentNoneBackPress(R.layout.fragment_home_detail) { +class HomeDetailFragment: BindingFragment(R.layout.fragment_home_detail) { private val viewModel: HomeViewModel by activityViewModels() @@ -19,6 +24,8 @@ class HomeDetailFragment: BindingFragmentNoneBackPress(R.layout.fragment_home_detail_info) { +class HomeDetailInfoFragment: BindingFragmentNoneBackPress(R.layout.fragment_home_detail_info), OnMapReadyCallback { private val viewModel : HomeViewModel by activityViewModels () + private lateinit var map: GoogleMap + + private var location = LatLng(0.0,0.0) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.viewModel = viewModel + binding.lifecycleOwner = viewLifecycleOwner setRecyclerView() } @@ -39,10 +51,24 @@ class HomeDetailInfoFragment: BindingFragmentNoneBackPress(R.layout.fragment_home_list) { +class HomeListFragment: BindingFragment(R.layout.fragment_home_list) { + + private val viewModel : HomeViewModel by activityViewModels () override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + binding.viewModel = viewModel binding.lifecycleOwner = viewLifecycleOwner + setButton() + val storeCouponAdapter = StoreCouponCountAdapter() binding.rvStore.apply { @@ -28,6 +34,7 @@ class HomeListFragment: BindingFragmentNoneBackPress(R. storeCouponAdapter.setOnItemClickListener(object : StoreCouponCountAdapter.OnItemClickListener { override fun onItemClick(id: Int) { val bundle = bundleOf("id" to id) + viewModel.loadStoreData() // TODO(추후 id를 활용한 데이터 요청 으로 변경) findNavController().navigate(R.id.action_homeListFragment_to_homeDetailFragment, bundle) } }) @@ -51,4 +58,15 @@ class HomeListFragment: BindingFragmentNoneBackPress(R. storeCouponAdapter.submitList(list) } + + private fun setButton() { + binding.btnToolbarBack.setOnClickListener { + onBackPressed() + } + } + + override fun onBackPressed() { + super.onBackPressed() + findNavController().popBackStack() + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMainFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMainFragment.kt index 3826a66..88db45d 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMainFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMainFragment.kt @@ -2,13 +2,16 @@ package com.umc.coumo.presentation.fragment import android.os.Bundle import android.view.View +import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.viewpager2.widget.ViewPager2 import com.umc.coumo.R import com.umc.coumo.databinding.FragmentHomeMainBinding import com.umc.coumo.domain.model.BannerCardModel -import com.umc.coumo.domain.model.StoreInfoModel +import com.umc.coumo.domain.model.StoreInfoItemModel +import com.umc.coumo.domain.type.CategoryType +import com.umc.coumo.domain.viewmodel.HomeViewModel import com.umc.coumo.presentation.adapter.BannerPagerAdapter import com.umc.coumo.presentation.adapter.StoreInfoAdapter import com.umc.coumo.utils.ItemSpacingDecoration @@ -16,6 +19,8 @@ import com.umc.coumo.utils.binding.BindingFragment class HomeMainFragment: BindingFragment(R.layout.fragment_home_main) { + private val viewModel : HomeViewModel by activityViewModels () + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -26,11 +31,39 @@ class HomeMainFragment: BindingFragment(R.layout.fragme private fun setButton() { binding.ivCafe.setOnClickListener { - val bundle = Bundle().apply { - putString("type","cafe") - } + viewModel.selectCategory(CategoryType.CAFE) + findNavController().navigate( + R.id.action_homeMainFragment_to_homeListFragment + ) + } + binding.ivRetail1.setOnClickListener { + viewModel.selectCategory(CategoryType.RETAIL1) + findNavController().navigate( + R.id.action_homeMainFragment_to_homeListFragment + ) + } + binding.ivFood.setOnClickListener { + viewModel.selectCategory(CategoryType.FOOD) + findNavController().navigate( + R.id.action_homeMainFragment_to_homeListFragment + ) + } + binding.ivRetail2.setOnClickListener { + viewModel.selectCategory(CategoryType.RETAIL2) findNavController().navigate( - R.id.action_homeMainFragment_to_homeSubFragment, bundle + R.id.action_homeMainFragment_to_homeListFragment + ) + } + binding.ivBeauty.setOnClickListener { + viewModel.selectCategory(CategoryType.BEAUTY) + findNavController().navigate( + R.id.action_homeMainFragment_to_homeListFragment + ) + } + binding.ivClass.setOnClickListener { + viewModel.selectCategory(CategoryType.CLASS) + findNavController().navigate( + R.id.action_homeMainFragment_to_homeListFragment ) } } @@ -44,18 +77,29 @@ class HomeMainFragment: BindingFragment(R.layout.fragme layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false) } - val list = listOf( - StoreInfoModel(1, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + val list = listOf( + StoreInfoItemModel(1, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(2, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(2, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(3, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(3, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), - StoreInfoModel(4, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + + StoreInfoItemModel(4, null,"앙떼띠 로스터리(강남점)", "강남구 테헤란로 43-7", "양떼띠 로스터리는 2017년에 오픈한 강남의 유명 카페입니다. 강남역 직장인들을 위해 평일 오전 7시~9시에\n" + "아메리카노 2000원 이벤트를 진행 중입니다."), ) storeInfoAdapter.submitList(list) + + storeInfoAdapter.setOnItemClickListener(object : StoreInfoAdapter.OnItemClickListener{ + override fun onItemClick(id: Int) { + + viewModel.loadStoreData() + findNavController().navigate( + R.id.action_homeMainFragment_to_homeDetailFragment, + ) + } + + }) } private fun setBanner() { diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMenuFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMenuFragment.kt index 258cdcf..a489026 100644 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMenuFragment.kt +++ b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeMenuFragment.kt @@ -4,16 +4,17 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.umc.coumo.R import com.umc.coumo.databinding.FragmentHomeMenuBinding import com.umc.coumo.domain.viewmodel.HomeViewModel import com.umc.coumo.presentation.adapter.MenuAdapter -import com.umc.coumo.utils.binding.BindingFragmentNoneBackPress +import com.umc.coumo.utils.binding.BindingFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -class HomeMenuFragment: BindingFragmentNoneBackPress(R.layout.fragment_home_menu) { +class HomeMenuFragment: BindingFragment(R.layout.fragment_home_menu) { private val viewModel : HomeViewModel by activityViewModels () @@ -21,7 +22,7 @@ class HomeMenuFragment: BindingFragmentNoneBackPress(R. super.onViewCreated(view, savedInstanceState) setRecyclerView() - + setButton() } private fun setRecyclerView() { @@ -32,10 +33,21 @@ class HomeMenuFragment: BindingFragmentNoneBackPress(R. layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) } - viewModel.menuList.observe(viewLifecycleOwner) { + viewModel.storeData.observe(viewLifecycleOwner) { viewLifecycleOwner.lifecycleScope.launch (Dispatchers.Main) { - menuAdapter.submitList(it) + menuAdapter.submitList(it.menuList) } } } + + private fun setButton() { + binding.btnToolbarBack.setOnClickListener { + onBackPressed() + } + } + + override fun onBackPressed() { + super.onBackPressed() + findNavController().popBackStack() + } } \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeSubFragment.kt b/app/src/main/java/com/umc/coumo/presentation/fragment/HomeSubFragment.kt deleted file mode 100644 index 2953efd..0000000 --- a/app/src/main/java/com/umc/coumo/presentation/fragment/HomeSubFragment.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.umc.coumo.presentation.fragment - -import android.os.Bundle -import android.view.View -import androidx.navigation.findNavController -import androidx.navigation.fragment.findNavController -import com.umc.coumo.R -import com.umc.coumo.databinding.FragmentHomeSubBinding -import com.umc.coumo.utils.binding.BindingFragment - -class HomeSubFragment: BindingFragment(R.layout.fragment_home_sub) { - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.btnToolbarBack.setOnClickListener { - onBackPressed() - } - } - - override fun onBackPressed() { - super.onBackPressed() - val innerNavController = binding.flHomeSub.findNavController() - val innerBackStackEntryCount = innerNavController.currentBackStack.value.size - - if (innerBackStackEntryCount > 2 ){ - innerNavController.popBackStack() - } else { - findNavController().popBackStack() - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/umc/coumo/utils/ApiResponse.kt b/app/src/main/java/com/umc/coumo/utils/ApiResponse.kt new file mode 100644 index 0000000..eb78818 --- /dev/null +++ b/app/src/main/java/com/umc/coumo/utils/ApiResponse.kt @@ -0,0 +1,12 @@ +package com.umc.coumo.utils + +import com.umc.coumo.domain.type.Status + + +data class ApiResponse(val status: Status, val data: T?, val throwable: Throwable?) { + companion object { + fun success(data: T): ApiResponse = ApiResponse(Status.SUCCESS, data, null) + fun error(throwable: Throwable): ApiResponse = ApiResponse(Status.ERROR, null, throwable) + fun loading(data: T? = null): ApiResponse = ApiResponse(Status.LOADING, data, null) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_rect_round_12.xml b/app/src/main/res/drawable/shape_rect_round_12.xml new file mode 100644 index 0000000..bb57fd0 --- /dev/null +++ b/app/src/main/res/drawable/shape_rect_round_12.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_detail.xml b/app/src/main/res/layout/fragment_home_detail.xml index db59ca5..7bdddb3 100644 --- a/app/src/main/res/layout/fragment_home_detail.xml +++ b/app/src/main/res/layout/fragment_home_detail.xml @@ -5,6 +5,7 @@ + @@ -14,146 +15,200 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - + + + + + + + + + android:layout_height="0dp" + app:layout_constraintTop_toBottomOf="@id/section_tool_bar" + app:layout_constraintBottom_toBottomOf="parent"> + + + + + + + + android:layout_height="match_parent"> - - - - + app:behavior_hideable="false" + app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"> - - + + - - - - - + app:layout_constraintTop_toTopOf="parent"/> + + - - - - + + + app:layout_constraintEnd_toStartOf="@id/tab_my_coupon"> + + + + + + + + + + + + - - + - - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_detail_info.xml b/app/src/main/res/layout/fragment_home_detail_info.xml index 24e35bb..ba1ab6e 100644 --- a/app/src/main/res/layout/fragment_home_detail_info.xml +++ b/app/src/main/res/layout/fragment_home_detail_info.xml @@ -3,7 +3,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> - + + android:layout_height="wrap_content" + android:paddingBottom="@dimen/bottom_above"> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_list.xml b/app/src/main/res/layout/fragment_home_list.xml index 5da5fda..e1ff267 100644 --- a/app/src/main/res/layout/fragment_home_list.xml +++ b/app/src/main/res/layout/fragment_home_list.xml @@ -3,98 +3,138 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> - + + - + android:layout_height="match_parent"> + + + + + + + + + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/section_tool_bar"> + android:layout_height="match_parent"> - - + android:id="@+id/section_locate_section" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="27dp" + android:paddingHorizontal="@dimen/horizontal_padding" + app:layout_constraintTop_toTopOf="parent"> - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/btn_refresh"> - + + - + - - - - + - - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_main.xml b/app/src/main/res/layout/fragment_home_main.xml index 3016744..ee42ce5 100644 --- a/app/src/main/res/layout/fragment_home_main.xml +++ b/app/src/main/res/layout/fragment_home_main.xml @@ -3,7 +3,10 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> - + + - + + - + android:layout_height="match_parent"> + style="@style/TabBarDefaultStyle" + app:layout_constraintTop_toTopOf="parent"> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + - + + + android:layout_height="match_parent" + android:paddingBottom="@dimen/bottom_above"> - + + + + + + + - + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_sub.xml b/app/src/main/res/layout/fragment_home_sub.xml deleted file mode 100644 index b50e50c..0000000 --- a/app/src/main/res/layout/fragment_home_sub.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_image_viewpager.xml b/app/src/main/res/layout/item_image_viewpager.xml new file mode 100644 index 0000000..a4c39eb --- /dev/null +++ b/app/src/main/res/layout/item_image_viewpager.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_menu.xml b/app/src/main/res/layout/item_menu.xml index 7de13f2..7a6a983 100644 --- a/app/src/main/res/layout/item_menu.xml +++ b/app/src/main/res/layout/item_menu.xml @@ -17,7 +17,7 @@ diff --git a/app/src/main/res/layout/item_store_info.xml b/app/src/main/res/layout/item_store_info.xml index 1f89ae5..4227fe3 100644 --- a/app/src/main/res/layout/item_store_info.xml +++ b/app/src/main/res/layout/item_store_info.xml @@ -6,7 +6,7 @@ + type="com.umc.coumo.domain.model.StoreInfoItemModel" /> diff --git a/app/src/main/res/navigation/nav_home.xml b/app/src/main/res/navigation/nav_home.xml index fee88da..310fa53 100644 --- a/app/src/main/res/navigation/nav_home.xml +++ b/app/src/main/res/navigation/nav_home.xml @@ -9,12 +9,30 @@ android:name="com.umc.coumo.presentation.fragment.HomeMainFragment" android:label="HomeMainFragment" > - + android:id="@+id/action_homeMainFragment_to_homeListFragment" + app:destination="@id/homeListFragment" /> + + + + + + + + android:id="@+id/homeMenuFragment2" + android:name="com.umc.coumo.presentation.fragment.HomeMenuFragment" + android:label="HomeMenuFragment" /> diff --git a/app/src/main/res/navigation/nav_home_sub.xml b/app/src/main/res/navigation/nav_home_sub.xml deleted file mode 100644 index 8c1dd8a..0000000 --- a/app/src/main/res/navigation/nav_home_sub.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 541463f..12eefed 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,4 +4,19 @@ plugins { id("org.jetbrains.kotlin.android") version "1.9.0" apply false id("com.android.library") version "8.1.3" apply false id("com.google.dagger.hilt.android") version "2.50" apply false +} +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath ("com.android.tools.build:gradle:7.0.4") + classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") + classpath ("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1") + } +} + +tasks.register("clean", Delete::class) { + delete(rootProject.buildDir) } \ No newline at end of file