Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 매장 상세 뷰 구현 #15

Merged
merged 39 commits into from
Nov 28, 2023
Merged

[feat] 매장 상세 뷰 구현 #15

merged 39 commits into from
Nov 28, 2023

Conversation

jihyunniiii
Copy link
Contributor

@jihyunniiii jihyunniiii commented Nov 27, 2023

Related issue 🛠

Work Description ✏️

  • 매장 상세 뷰를 구현했습니다.

Screenshot 📸

Screen_recording_20231128_165450.mp4

Uncompleted Tasks 😅

  • ViewPager2 내부 Fragment 스크롤 안 되는 문제 해결 => ViewPager 사용하지 않고 NestedScollView 사용했습니다.

To Reviewers 📢

칭찬해주삼 칭찬 받고 시픔

# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/res/drawable/ic_star_yellow_14.xml
#	app/src/main/res/values/colors.xml
#	app/src/main/res/values/strings.xml
#	app/src/main/res/values/themes.xml
Copy link
Member

@Doreminwoo Doreminwoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무너무 고생하셨습니다.
볼게 너무 많아서 입국하면 코드를 구석구석 봐야겠어요!

@@ -0,0 +1,21 @@
package org.sopt.tabling.domain.model

data class ShopDetail(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 서버 통신이 아니라서 리스폰스 대신 데이터클래스로 하신건가요!?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클린 아키텍처를 적용하려고 데이터 클래스로 하였숩니당
클린 아키텍처에서는 data 모델에 dto 적구, domain 계층에서 필요한 정보들만 data class를 만들어서 매핑해서 사용해용
https://jihyunniiii.notion.site/MVVM-Clean-Achitecture-353a837d67b54f959881d1811d4c8eb5?pvs=4
예전에 정리해둔 건데 여유 있을 때 한 번 읽어보시면 좋을 듯 합니당 !

initLayout()
}

private fun initLayout() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 이런식으로 코드를 작성해서 onCreate의 코드양을 줄이는건가요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

알아보기 쉬우라구 함수화 했숩니당
원래 initLayout에 binding하는 로직들을 다 적는 편인데 요 뷰는 바인딩 할 게 너무 많아서 함수를 나눴서용 !

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 가독성 너무 좋아요 initLayout으로 한 번 더 빼는게 짱짱!!!!

)
}

private fun initShopDetailAppBar() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 신기하네요 나중에 코드좀 자세히 봐야겠어요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이게 진짜 하면서 눈물날 뻔 했던,,,, 나중에 요런 거 하게 되시면 참고하세용

)
}

companion object {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수화 너무 멋있다...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 민우오빠가 코리로 상수화하라고 한게 이런거였군요 징짜 많이 배워갑니다.. 이해 못해서 우짜지 우짜지 했는데ㅜㅜ

import org.sopt.tabling.domain.model.Menu
import org.sopt.tabling.util.ItemDiffCallback

class ShopDetailMenuListAdapter() : ListAdapter<Menu, ShopDetailMenuListViewHolder>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 이것이 리스트어댑터! 볼 것이 많네요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리스트 어댑터 꼭꼭 공부해보깅 !!!

android:layout_height="wrap_content">

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_item_shop_detail_menu_img"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 imageView 이미지만 사용하는 것이 아니니깐 맨 뒤에 img 정도는 붙여주는게 더 좋겠네요!

android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.constraintlayout.widget.Guideline
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 이런것도 있군요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 진짜 짱 편합니당 하나하나 마진 안 주고 얘로 한 번에 쇽 가능

# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/org/sopt/tabling/presentation/dummy/DummyViewModel.kt
#	app/src/main/res/values/strings.xml
Copy link
Contributor

@HAJIEUN02 HAJIEUN02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

교과서 그 자체 .. 코드리뷰의 진가를 알게 된 것 같아요 아예 모를 때보다 지금 어느 정도 배우고 보니까 대단한 코드라는게 느껴지네욥 나중에 서버 통신에서도 많이 배울 수 있기를 기대하겠습니당 !! 수고 많아써여 어려운 뷰ㅠ ㅠ 맡아줘서 고마버용🧡


data class Menu(
val menuCategory: String,
val menuInfoList: List<MenuInfo>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 List는 이런 식으로 하면 되는 거군용 안그래도 딱 어제 데이터 클래스에 리스트는 어떻게 하지 고민했는데!!!!

initLayout()
}

private fun initLayout() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 가독성 너무 좋아요 initLayout으로 한 번 더 빼는게 짱짱!!!!

private fun initShopDetailAppBar() {
with(binding) {
shopDetailViewModel?.let { shopDetailViewModel ->
chipShopDetailWaiting.text = getString(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네이밍을 잘하셨네요.. 네이밍 너무 어려운 것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네이밍,,, 저도 진짜 아직까지 넘 어려워요 ㅠ 네이밍 잘 하고 싶따

)
}

ablShopDetail.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addOnOffsetChangedListener는 검색해도 잘 안 나오는데 정확히 어떤 역할을 하는 친구인가요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거는 제가 어제 자랑했던,,! 스크롤이 하단으로 내려갔을 때 앱바의 색상이 변경되는 걸 구현하고 사용한 칭구입니다.
저도 처음 사용해본 건데요,,! 생각보다 쓸 일이 많이 없는 것 같아요
appBarLayout의 위치값이 변하는 걸 읽은 후 필요한 로직들을 처리해주는 칭구라고 생각해주면 됩니당
저는 backgroud 색상, icon 색상을 변경하기 위해 사용했어오

private fun initShopDetailHome() {
with(binding) {
shopDetailViewModel?.let { shopDetailViewModel ->
tvShopDetailHomeSalesTime.text = shopDetailViewModel.mockShopDetailInfo.salesTime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버통신할 때는 요기 뷰모델 쓰던게 서버통신 코드로 바뀌는건가요 아니면 뷰모델에 서버통신한 값을 저장하는 건가요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 서버통신 결과 값을 저장해주는 liveData(Flow를 쓸 수도 있구요,,! 아직 고민 중)를 하나 만들어서 결과값을 저장한 다음에 그 데이터를 옵저빙해서 값을 binding 해주는 식으로 구현할 예정이에용 !


class ShopDetailMenuAdapter() : ListAdapter<MenuInfo, ShopDetailMenuViewHolder>(
ItemDiffCallback<MenuInfo>(
onContentsTheSame = { old, new -> old == new },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notifyDataSetChanged() 대신 DiffUtil 사용하기 머리에 기억해두겠숩니다 앱잼때는 꼭!!!!!!!!!!!!!!!!!!11

import org.sopt.tabling.domain.model.Menu
import org.sopt.tabling.util.ItemDiffCallback

class ShopDetailMenuListAdapter() : ListAdapter<Menu, ShopDetailMenuListViewHolder>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

친구가 ListAdapter 써서 만들어놓구 설명을 못 해주길래.. 대체 저게 뭐지 했는데 좋은 거였구납ㅎ 리사이클러뷰가 짱인 줄 알았어요 역시 배울게 넘 많은 세상

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 리사이클러뷰를 구현할 때 NotifyDataSetChanged라는 칭구를 사용할 텐데요
이 친구는 데이터가 변경되는 경우 데이터를 모두 업데이트 시켜버려요 ! 데이터의 일부가 변경되어도 데이터의 전체가 업데이트 되는 셈이죠 ! 근데 리사이클러뷰는 우리가 재사용을 하기 위해 사용하는 칭군데 이렇게 데이터가 다 변경되어 버리면 굉장히 비효율적이고 리사이클러뷰의 장점을 살리지 못하게 되겠죠??
그래서 사용하는 게 DiffUtil 과 ListAdapter 입니당 !
https://jihyunniiii.notion.site/DiffUtil-ListAdapter-92dddcaf0dfe41cfa94d591a5abff9dc?pvs=4
제가 와비 때 정리한 노션 링큰데,, 필요하면 보면서 공부해보셔용

android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20.166,9.346L20.471,9.041C20.73,8.782 20.73,8.361 20.471,8.101C20.211,7.841 19.79,7.841 19.53,8.101L19.218,8.413L18.618,6.013C18.403,5.152 17.538,4.477 16.651,4.477H7.349C6.462,4.477 5.598,5.152 5.382,6.013L4.782,8.413L4.47,8.101C4.21,7.841 3.789,7.841 3.529,8.101C3.27,8.361 3.27,8.782 3.529,9.041L3.834,9.346C2.862,9.823 2.192,10.822 2.192,11.975V14.311C2.192,15.253 2.64,16.093 3.335,16.628V17.794C3.335,18.747 4.11,19.522 5.063,19.522H6.364C7.318,19.522 8.093,18.747 8.093,17.794V17.237H15.907V17.794C15.907,18.747 16.682,19.522 17.636,19.522H18.937C19.89,19.522 20.666,18.747 20.666,17.794V16.628C21.36,16.093 21.809,15.253 21.809,14.311V11.975C21.809,10.822 21.138,9.823 20.166,9.346ZM6.046,8.843L6.672,6.336C6.74,6.064 7.069,5.807 7.349,5.807H16.651C16.931,5.807 17.26,6.064 17.328,6.336L17.955,8.843C17.972,8.913 17.968,8.972 17.945,9.002C17.922,9.031 17.865,9.049 17.794,9.049H6.206C6.135,9.049 6.078,9.031 6.055,9.002C6.032,8.972 6.028,8.913 6.046,8.843ZM3.522,11.975C3.522,11.095 4.238,10.379 5.118,10.379H18.883C19.763,10.379 20.479,11.095 20.479,11.975V14.311C20.479,15.191 19.763,15.907 18.883,15.907H5.118C4.238,15.907 3.522,15.191 3.522,14.311V11.975ZM6.763,17.794C6.763,18.01 6.581,18.193 6.364,18.193H5.063C4.847,18.193 4.664,18.01 4.664,17.794V17.201C4.812,17.225 4.963,17.237 5.117,17.237H6.763V17.794H6.763ZM19.336,17.794C19.336,18.01 19.153,18.193 18.937,18.193H17.636C17.42,18.193 17.237,18.01 17.237,17.794V17.237H18.883C19.037,17.237 19.188,17.225 19.336,17.201V17.794H19.336Z"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pathData는 이미지인가요?? 오마이갓 내 눈알

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거능 svg 넣으면 자동으로 만들어주는 파일이라 유심히 볼 필요없서용 ㅋ.ㅋ
아마 이미지 그려지는 부분 나타내주는 것 같움요 !

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 파일명 네이밍에도 적응해야 하는데ㅜㅅㅠ 파일명 다 너무 야물딱지고 한 눈에 잘 보이네용 참고할게욥!!

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="음식 맛" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tools:text 애용하겠습니다! 저번 언니 코리 이후로 학교 프젝에선 전부 tools 쓰구 잇어욥ㅎㅎ❤❤

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

키키 조씀다 🤍 야무진 우리 지으니 짱

@jihyunniiii jihyunniiii merged commit 3039fa3 into develop Nov 28, 2023
1 check passed
@jihyunniiii jihyunniiii deleted the feat-shop-detail-view branch November 28, 2023 15:14
Copy link

@Dan2dani Dan2dani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

머지했지만 간략하게라도 코리답니당! 오늘도 열심히 보다가 일단 탈주,,

initLayout()
}

private fun initLayout() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adapter 전부 onDestroy()에서 해제해주세요!
adapter가 참조한 뷰나 객체는 gc에 의해서 자동 해제 되지 못한다고 하네요

ContextCompat.getColor(this@ShopDetailActivity, R.color.gray_800)
) as Int

ivShopDetailBack.setImageDrawable(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coil로 로드할 수도 있지 않나염~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

화면이 스크롤 되면 저 이미지가 white -> gray_800으로 변경되어야 해서 colorFilter를 적용하였는데요,,! coil로 로드하면 colorFilter 사용이 쉽지 않더라구요,,, 그래서 구냥 setImageDrawable로 구현하였습니당

shopDetailViewModel.mockShopDetailInfo.hashTagList.forEachIndexed { index, hashTag ->
cgShopDetailHomeShopPick.addView(
Chip(
ContextThemeWrapper(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동적으로 추가하면 xml에서 스타일을 지정할 수 없다는게 무슨 말일까요!
xml에 칩 스타일을 하나 만들어놓고, 해당 뷰를 inflate 시켜서 칩 객체를 생성할 수도 있습니다

}
}

private fun initShopDetailRecentReview() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 먼가 정리가 필요해보이긴 하는군요,,

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와웅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋㅋ 저 이거 좀 정리했서요
새로 피알 올릴테니 구경오셔요

}
}

private fun initTabLayout() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 이렇게 했군용!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 어케 한건지 궁금했음 짱이다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

키킼 와서 코리 달아주는 안빵이들 사랑 하구 보고 싶구 🤍🍞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[feat] 매장 상세 뷰 구현
5 participants