Skip to content

Commit

Permalink
#10 [ui] 가게 상세화면 UI
Browse files Browse the repository at this point in the history
#10 [ui] 가게 상세화면 UI
  • Loading branch information
NaZe0320 authored Jan 28, 2024
2 parents 5ca8458 + 8f5ad17 commit 04b8f94
Show file tree
Hide file tree
Showing 30 changed files with 1,234 additions and 11 deletions.
11 changes: 11 additions & 0 deletions app/src/main/java/com/umc/coumo/domain/model/MenuModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.coumo.domain.model

import android.net.Uri

data class MenuModel(
val id: Int,
val name: String,
val content: String,
val image: Uri? = null,
val isNew: Boolean = false
)
6 changes: 6 additions & 0 deletions app/src/main/java/com/umc/coumo/domain/type/DetailTabType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.umc.coumo.domain.type

enum class DetailTabType {
INFO,
COUPON,
}
38 changes: 38 additions & 0 deletions app/src/main/java/com/umc/coumo/domain/viewmodel/HomeViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.umc.coumo.domain.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.umc.coumo.domain.model.MenuModel
import com.umc.coumo.domain.type.DetailTabType
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class HomeViewModel @Inject constructor(): ViewModel() {

private val _currentTab = MutableLiveData(DetailTabType.INFO)
val currentTab: LiveData<DetailTabType> get() = _currentTab

private val _menuList = MutableLiveData<List<MenuModel>>()
val menuList: LiveData<List<MenuModel>> get() = _menuList

init {
testData()
}

fun changeTab(tab: DetailTabType) {
_currentTab.value = tab
}

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",),
)
_menuList.value = list
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.umc.coumo.presentation.activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.umc.coumo.R
import com.umc.coumo.databinding.ActivityMainBinding
import com.umc.coumo.domain.type.TabType
Expand All @@ -29,6 +26,14 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
binding.viewpager.isUserInputEnabled = false //스와이프 방지

setNaviButton()
setObserver()
}

private fun setObserver () {
viewModel.currentPageIndex.observe(this) {
if (it == TabType.COUPON)
binding.viewpager.setCurrentItem(1, true)
}
}

private fun setNaviButton() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.umc.coumo.presentation.adapter

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.umc.coumo.presentation.fragment.HomeDetailCouponFragment
import com.umc.coumo.presentation.fragment.HomeDetailInfoFragment

class HomeDetailViewPagerAdapter(fragment: FragmentActivity): FragmentStateAdapter(fragment) {
val fragments: ArrayList<Fragment> = arrayListOf(HomeDetailInfoFragment(), HomeDetailCouponFragment())

override fun getItemCount(): Int {
return fragments.size
}

override fun createFragment(position: Int): Fragment {
return fragments[position]
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.umc.coumo.presentation.adapter


import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.umc.coumo.databinding.ItemMenuBinding
import com.umc.coumo.databinding.ItemMenuDetailBinding
import com.umc.coumo.domain.model.MenuModel
import com.umc.coumo.utils.ItemDiffCallback

class MenuAdapter(
private val type: Int
): ListAdapter<MenuModel, RecyclerView.ViewHolder>(
ItemDiffCallback<MenuModel>(
onContentsTheSame = {old, new -> old == new},
onItemsTheSame = {old, new -> old.id == new.id}
)
) {
companion object {
const val MENU_ITEM = 0
const val MENU_DETAIL_ITEM = 1
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (type) {
MENU_ITEM -> {
MenuViewHolder(ItemMenuBinding.inflate(inflater, parent,false))
}
MENU_DETAIL_ITEM -> {
MenuDetailViewHolder(ItemMenuDetailBinding.inflate(inflater, parent,false))
}
else -> throw IllegalArgumentException("Invalid viewType")
}
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)

when (holder) {
is MenuViewHolder -> {
holder.bind(item)
}
is MenuDetailViewHolder -> {
holder.bind(item)
}
}
}



inner class MenuViewHolder(
private val binding: ItemMenuBinding
): RecyclerView.ViewHolder(binding.root) {
fun bind(item: MenuModel) {
binding.item = item

itemView.setOnClickListener {
listener?.onItemClick(item.id)
}
}
}

inner class MenuDetailViewHolder(
private val binding: ItemMenuDetailBinding
): RecyclerView.ViewHolder(binding.root) {
fun bind(item: MenuModel) {
binding.item = item

itemView.setOnClickListener {
listener?.onItemClick(item.id)
}
}
}

interface OnItemClickListener {
fun onItemClick(id:Int)
}

private var listener: OnItemClickListener? = null

fun setOnItemClickListener(listener: OnItemClickListener) {
this.listener = listener
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.umc.coumo.presentation.fragment

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import com.umc.coumo.R
import com.umc.coumo.databinding.FragmentHomeDetailCouponBinding
import com.umc.coumo.domain.type.TabType
import com.umc.coumo.domain.viewmodel.MainViewModel
import com.umc.coumo.utils.binding.BindingFragmentNoneBackPress

class HomeDetailCouponFragment: BindingFragmentNoneBackPress<FragmentHomeDetailCouponBinding>(R.layout.fragment_home_detail_coupon) {

private val viewModel: MainViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.tvCouponCollection.setOnClickListener {
viewModel.changePageIndex(TabType.COUPON)
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.umc.coumo.presentation.fragment

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
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

class HomeDetailFragment: BindingFragmentNoneBackPress<FragmentHomeDetailBinding>(R.layout.fragment_home_detail) {

private val viewModel: HomeViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.viewModel = viewModel
binding.lifecycleOwner = viewLifecycleOwner
setViewPager()
}

private fun setViewPager() {
val pagerAdapter = HomeDetailViewPagerAdapter(requireActivity())

viewModel.changeTab(DetailTabType.INFO)

binding.vpStore.apply {
adapter = pagerAdapter
offscreenPageLimit = 1
isUserInputEnabled = false //스와이프 방지
}

binding.tabStoreInfo.setOnClickListener {
binding.vpStore.setCurrentItem(0, true)
viewModel.changeTab(DetailTabType.INFO)
}
binding.tabMyCoupon.setOnClickListener {
binding.vpStore.setCurrentItem(1, true)
viewModel.changeTab(DetailTabType.COUPON)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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 androidx.recyclerview.widget.LinearLayoutManager
import com.umc.coumo.R
import com.umc.coumo.databinding.FragmentHomeDetailInfoBinding
import com.umc.coumo.domain.viewmodel.HomeViewModel
import com.umc.coumo.presentation.adapter.MenuAdapter
import com.umc.coumo.utils.ItemSpacingDecoration
import com.umc.coumo.utils.binding.BindingFragmentNoneBackPress
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class HomeDetailInfoFragment: BindingFragmentNoneBackPress<FragmentHomeDetailInfoBinding>(R.layout.fragment_home_detail_info) {

private val viewModel : HomeViewModel by activityViewModels ()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

setRecyclerView()
}

private fun setRecyclerView() {
val menuAdapter = MenuAdapter(0)

binding.rvMenu.apply {
adapter = menuAdapter
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
addItemDecoration(ItemSpacingDecoration(requireContext(),0))
}

menuAdapter.setOnItemClickListener(object : MenuAdapter.OnItemClickListener {
override fun onItemClick(id: Int) {
findNavController().navigate(R.id.action_homeDetailFragment_to_homeMenuFragment)
}
})

viewModel.menuList.observe(viewLifecycleOwner) {
viewLifecycleOwner.lifecycleScope.launch (Dispatchers.Main) {
menuAdapter.submitList(it)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.umc.coumo.presentation.fragment

import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.umc.coumo.R
import com.umc.coumo.databinding.FragmentHomeListBinding
import com.umc.coumo.domain.model.StoreCouponCountModel
import com.umc.coumo.presentation.adapter.StoreCouponCountAdapter
import com.umc.coumo.utils.binding.BindingFragmentNoneBackPress

class HomeListFragment: BindingFragmentNoneBackPress<FragmentHomeListBinding>(R.layout.fragment_home_list) {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.lifecycleOwner = viewLifecycleOwner

val storeCouponAdapter = StoreCouponCountAdapter()

binding.rvStore.apply {
adapter = storeCouponAdapter
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
}

storeCouponAdapter.setOnItemClickListener(object : StoreCouponCountAdapter.OnItemClickListener {
override fun onItemClick(id: Int) {
val bundle = bundleOf("id" to id)
findNavController().navigate(R.id.action_homeListFragment_to_homeDetailFragment, bundle)
}
})

//테스트 코드
val list = listOf<StoreCouponCountModel>(
StoreCouponCountModel(1, null,"앙떼띠 로스터리(강남점)", 2),
StoreCouponCountModel(2, null,"앙떼띠 로스터리(강남점)", 5),
StoreCouponCountModel(3, null,"앙떼띠 로스터리(강남점)", 4),
StoreCouponCountModel(4, null,"앙떼띠 로스터리(강남점)", 3),
StoreCouponCountModel(5, null,"앙떼띠 로스터리(강남점)", 10),
StoreCouponCountModel(6, null,"앙떼띠 로스터리(강남점)", 0),
StoreCouponCountModel(11, null,"앙떼띠 로스터리(강남점)", 2),
StoreCouponCountModel(21, null,"앙떼띠 로스터리(강남점)", 5),
StoreCouponCountModel(31, null,"앙떼띠 로스터리(강남점)", 4),
StoreCouponCountModel(41, null,"앙떼띠 로스터리(강남점)", 3),
StoreCouponCountModel(51, null,"앙떼띠 로스터리(강남점)", 10),
StoreCouponCountModel(61, null,"앙떼띠 로스터리(강남점)", 0),
)

storeCouponAdapter.submitList(list)

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.umc.coumo.presentation.fragment

import android.os.Bundle
import android.view.View
import androidx.navigation.fragment.findNavController
import com.umc.coumo.R
import com.umc.coumo.databinding.FragmentHomeMainBinding
import com.umc.coumo.utils.binding.BindingFragment

class HomeMainFragment: BindingFragment<FragmentHomeMainBinding>(R.layout.fragment_home_main) {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.btnTest.setOnClickListener {
findNavController().navigate(R.id.action_homeMainFragment_to_homeSubFragment)
}
}
}
Loading

0 comments on commit 04b8f94

Please sign in to comment.