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] 코스 발견 / 중첩 리사이클러뷰에서 추천 코스 무한 스크롤 #301

Merged

Conversation

leeeha
Copy link
Member

@leeeha leeeha commented Dec 20, 2023

📌 개요

✨ 작업 내용

구현한 알고리즘을 설명하자면 다음과 같습니다.

  1. 외부 리사이클러뷰의 스크롤이 최하단까지 도달했는지 검사합니다. (canScrollVertically 함수 이용)
  2. 페이지의 isEnd 속성이 false 여서 다음 페이지를 요청할 수 있는 경우, 서버로부터 다음 페이지를 불러옵니다.
  3. 불러온 새 데이터를 외부 리사이클러뷰의 추천 코스 리스트에 추가합니다.
  4. 외부 리사이클러뷰에서 notifyItemChanged(recommendPosition) 함수를 호출합니다.
  5. 그러면 추천 코스 리사이클러뷰는 다시 바인딩 되면서, 새 데이터가 추가된 리스트를 submit 합니다.

✨ PR 포인트

  • 외부 리사이클러뷰에서 notifyItemChanged(recommendPosition) 함수를 호출하면, 추천 코스 리스트 전체가 다시 갱신되는 거 같아요. 이보다 더 효율적인 무한 스크롤 방법을 알고 계시다면 꼭 코멘트 남겨주세요 🙏🙏
  • 코스 상세페이지에서 스크랩 개수 바로 갱신되는 기능은 별도의 브랜치에서 작업했고, 따로 pr 올릴 예정입니다.

📸 스크린샷/동영상

nse-4926098677937598786-1000016434.1.mp4

서버 측에서 더미 데이터로 추천 코스 쪽에도 마라톤 코스를 넣어뒀는데, 이 경우에는 상세페이지에서 스크랩 버튼 눌러도 바로 이전 화면에 반영되지 않더라구요..! 그리고 추천 코스 데이터가 완전히 똑같은 데이터 클래스인 경우에도 스크랩 반영이 바로 되지 않는 거 같았어요!

이 부분은 클라 코드보다는 서버 측 데이터와 관련된 문제인 거 같습니다! 추천 코스 데이터가 마라톤 코스가 아니면서 모두 다른 데이터 클래스라면, 이 문제는 해결될 것으로 보입니다.

…into feature/fix-detail-to-discover-update
- 마라톤 코스 뷰홀더 안에서 어댑터의 notifyItemChanged 함수 호출하도록
…into feature/fix-detail-to-discover-update
- 리스트를 따로 만들지 않고 어댑터에서 가져와 사용하도록
@leeeha leeeha self-assigned this Dec 20, 2023
@unam98 unam98 force-pushed the develop branch 2 times, most recently from 9538b84 to 55b4ded Compare December 20, 2023 13:17
Copy link
Member

@dongx0915 dongx0915 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~
간단하게만 봤는데 나중에 시간 날 때 풀 받아서 좀 더 꼼꼼히 볼게요!

…into feature/feat-discover-recommend-course-infinite-scroll

# Conflicts:
#	app/src/main/java/com/runnect/runnect/data/repository/CourseRepositoryImpl.kt
- notifyItemInserted 대신에 notifyItemChanged 함수를 사용하기 때문에, 추천 코스의 헤더와 리스트 영역을 구분할 필요가 없어짐.
- 인자로 gravity 전달하도록 변경
- CoordinatorLayout 사용하는 코스 발견 페이지에서만 스낵바가 상단에 뜨도록
@leeeha leeeha requested a review from dongx0915 December 26, 2023 15:27
Copy link
Contributor

@unam98 unam98 left a comment

Choose a reason for hiding this comment

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

리뷰가 너무 늦어졌네요 쏘리
comment 확인 부탁드립니다! 수고 많으셨습니다!!

Comment on lines +55 to +60
fun addRecommendCourseNextPage(nextPageCourses: List<RecommendCourse>) {
// 외부 리사이클러뷰의 추천 코스 리스트 갱신 -> 내부 리사이클러뷰 재바인딩 -> 새로운 데이터 submitList
val position = DiscoverMultiViewType.RECOMMEND.ordinal
currentList[position].addAll(nextPageCourses)
notifyItemChanged(position)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

pr 코멘트 적어주신 부분이 여기죠?!

우리가 보통 쓰는 ListAdapter랑 DiffUtil은 기존의 RecyclerView.adapter에서도 할 수 있는 처리들을 편의상 자동으로 수행될 수 있게 발전시킨 형태로 알고 있는데요.

이렇게 자동적으로 처리되게 된 부분을 직접 구현해주면 되지 않을까요?
https://hungseong.tistory.com/24

추가로 멀티뷰에서도 ListAdapter를 쓸 수 있는데 RecyclerView.adapter를 쓰신 이유가 있으신가요?

Copy link
Member Author

@leeeha leeeha Jan 3, 2024

Choose a reason for hiding this comment

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

ListAdapter를 사용하려면 아래와 같은 DiffUtil.ItemCallback 객체를 만들어줘야 합니다.

private val diffUtil = ItemDiffCallback<DiscoverMultiViewItem.MarathonCourse>(
    onItemsTheSame = { old, new -> old.id == new.id },
    onContentsTheSame = { old, new -> old == new }
)
class ItemDiffCallback<T : Any>(
    val onItemsTheSame: (T, T) -> Boolean,
    val onContentsTheSame: (T, T) -> Boolean
) : DiffUtil.ItemCallback<T>() {
    override fun areItemsTheSame(
        oldItem: T,
        newItem: T
    ): Boolean = onItemsTheSame(oldItem, newItem)

    override fun areContentsTheSame(
        oldItem: T,
        newItem: T
    ): Boolean = onContentsTheSame(oldItem, newItem)
}

DiffUtil은 두 데이터셋을 받아서 그 차이를 계산해주는 클래스여서, DiffUtil을 사용하면 두 데이터셋을 비교한 뒤 그중 변한 부분만을 파악하여 Recyclerview에 반영할 수 있다고 합니다.

이때 보통 DiffUtil.ItemCallback<T>의 제네릭 타입 T에는 데이터 클래스를 넣었는데, 현재는 중첩 리사이클러뷰로 구현되어 있다 보니, T에 어떤 데이터를 넣어줘야 할지 감이 오지 않아서 기본 RecyclerView.Adapter를 사용했습니다!

혹시 방법을 알고 계시다면 힌트 주실 수 있나요??

Copy link
Contributor

Choose a reason for hiding this comment

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

고민해보겠습니다! pr closed돼도 이 이슈 휘발되지 않게 노션에 아카이빙 부탁드립니다 :)

Copy link
Contributor

@unam98 unam98 left a comment

Choose a reason for hiding this comment

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

하은이가 있어 든든하다~ 나도 분발해볼게

- 코스 발견 리사이클러뷰의 멀티 뷰 홀더 팩토리 내부 코드에 적용
@leeeha leeeha merged commit 3013cd7 into develop Jan 5, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FEAT ✨ 새로운 기능 구현 MOD ☁ 코드 및 내부 파일 수정 하은 🐰 하은 담당
Projects
Development

Successfully merging this pull request may close these issues.

[FEAT] 코스 발견 / 추천 코스 무한 스크롤
3 participants