본문 바로가기

Projects/FineByMe8

[Android/Kotlin] Jetpack Compose + Paging3로 무한 스크롤 구현하기 사진 리스트처럼 무한히 스크롤되는 데이터를 효율적으로 불러오려면, 모든 데이터를 한 번에 불러오는 것이 아니라 필요할 때 필요한 만큼만 로드하는 방식이 필요합니다.Jetpack Compose에서는 Paging3와 함께 이를 쉽게 구현할 수 있습니다.이 글에서는 Unsplash API를 예시로, PagingSource, Pager, PagingData, 그리고 LazyPagingItems를 어떻게 연결하는지를 공부한 내용을 기반으로 정리해보았습니다.1. 의존성 추가먼저 build.gradle에 아래와 같이 Paging 관련 의존성을 추가합니다.// 필수: Paging 로직의 핵심 구성implementation("androidx.paging:paging-runtime:3.3.2")// 선택: Paging 데.. 2025. 5. 15.
[Android/Kotlin] Jetpack Compose에서 Flow.debounce()로 검색 요청 최적화하기 프로젝트에서 실시간 사진 검색 기능을 구현하던 중, 검색어 입력 시마다 API가 호출되는 문제가 있었습니다.예를 들어 사용자가 "dinosaur"를 입력하면 "d", "di", "din" 등 입력하는 매 글자마다 API 요청이 발생했기 때문에 불필요한 호출이 많아지고 사용자 경험에도 영향을 주고 있었습니다.이 문제를 해결하기 위해 Flow.debounce()를 적용해 검색 흐름을 개선해보았습니다.문제 상황: 과도한 API 호출처음에는 TextField의 onValueChange에서 바로 API를 호출하고 있었기 때문에, 아래와 같이 입력할 때마다 로그가 찍히고 요청이 전송되었습니다. 이처럼 한 글자 입력할 때마다 API 요청이 발생해 사용량이 과도하게 늘고로딩 UI가 계속 깜빡이는 등 UX에도 부정적인 .. 2025. 5. 7.
[Android/Kotlin] Room + Flow 조합으로 즐겨찾기 화면 자동 갱신하기 Jetpack Compose로 마이그레이션을 진행하면서, 기존 LiveData 기반의 ViewModel 코드를StateFlow + Flow 중심 구조로 함께 개선했습니다.특히 즐겨찾기 화면에서는 그동안 LiveData 기반으로 onResume() 시점마다 수동으로 데이터를 다시 불러와야 했는데요,이번에는 StateFlow와 Room + Flow 조합을 통해 자동으로 갱신되는 UI 흐름으로 전환하게 되었습니다.이를 통해 어떤 점이 개선되었고, 실제로 어떤 구조의 차이가 있었는지 정리해보고자 합니다.기존 방식: 수동 갱신이 필요했던 구조기존에는 ViewModel 내부에서 다음과 같이 데이터를 불러오는 방식을 사용하고 있었습니다.private fun loadFavoritePhotos() { viewMod.. 2025. 4. 24.
[Android/Kotlin] BaseViewModel을 걷어내고 원본 비율을 살린 Masonry 레이아웃 개선기 Pinterest 스타일의 UI를 구현하기 위해, 저는 처음에 각 이미지 카드의 높이를 랜덤하게 설정하는 방식으로 StaggeredGrid를 구성했습니다.이때는 ViewModel에 높이 계산 로직을 두고 position을 기준으로 랜덤한 값을 생성해서 캐싱했으며, 이를 여러 Fragment에서 공통으로 사용하기 위해 BaseViewModel을 상속받는 구조를 사용했었습니다.하지만 프로젝트의 주요 UI를 Jetpack Compose로 마이그레이션하면서,사진 콘텐츠를 더 자연스럽고 의미 있게 표현하기 위한 Masonry 스타일의 본질을 다시 생각하게 되었고, 그 결과 ViewModel 기반 구조는 제거하고 확장 함수를 활용한 방향으로 리팩터링하게 되었습니다.문제점: 랜덤한 높이는 시각적 흥미를 줄 수 있지만.. 2025. 4. 14.
[Android/Kotlin] StaggeredGridLayout 사용시 발생한 화면 재구성문제 수정 최근에 StaggeredGridLayoutManager를 사용한 즐겨찾기 화면에서 다음과 같은 문제가 발생했습니다:즐겨찾기 화면에서 첫 번째 사진을 클릭하여 상세 보기로 이동사진 상세 화면에서 즐겨찾기를 해제뒤로 가기를 눌러 다시 즐겨찾기 화면으로 돌아오면 빈 화면이 보여짐이 문제는 StaggeredGridLayoutManager에서 아이템을 재배치하는 과정에서 발생했습니다. 아이템들을 제대로 불러오지 못하고 화면을 재구성하는 데 실패하여 빈 화면을 보여주게 된 것입니다.이 문제를 해결하기 위해 RecyclerView의 상태를 복원하는 방법을 적용했습니다. 이를 통해 화면이 빈 화면으로 나타나는 현상을 해결할 수 있었습니다. 다음은 해결 방법입니다.해결 방법: RecyclerView 상태 복원Recycl.. 2024. 7. 29.
[Android/Kotlin]FineByMe 프로젝트 리팩토링: RecyclerView.Adapter에서 ListAdapter로의 전환 최근 FineByMe 프로젝트를 리팩토링하면서, RecyclerView.Adapter에서 ListAdapter로 전환하는 과정에서 많은 것을 배웠습니다. 이 글에서는 그 과정을 공유하고, ListAdapter가 왜 더 효율적인지 설명하고자 합니다.RecyclerView.Adapter에서 DiffUtil을 사용한 구현기존에 RecyclerView.Adapter를 사용할 때, DiffUtil을 사용하여 데이터 변경 사항을 처리하기 위해 추가적인 코드를 작성해야 했습니다. 아래는 그 예시입니다.class PhotoAdapter(private val viewModel: BaseViewModel) : RecyclerView.Adapter() { private var photoList: List = li.. 2024. 7. 10.
[Android/Kotlin] Retrofit 에러 처리 방법: HttpException을 활용한 상태 코드별 에러 메시지 처리 최근 프로젝트에서 Unsplash API를 사용하면서 발생한 에러를 상태 코드별로 처리하는 방법을 공유하고자 합니다. 이 과정에서 Retrofit을 활용하여 서버 응답을 효율적으로 처리할 수 있는 방법을 알게 되었습니다. 특히, HttpException을 활용하여 상태 코드별로 에러 메시지를 처리하는 방법에 대해 자세히 설명드리겠습니다.문제 상황처음에는 Unsplash API를 호출할 때 잘못된 API 키를 사용하여 401 Unauthorized 에러를 발생시키고 이를 처리하고자 했습니다. 하지만 예상과 달리 onFailure 콜백이 호출되지 않았습니다. 이에 대해 원인을 분석하고 해결하는 과정을 통해 Retrofit의 에러 처리 방식을 이해하게 되었습니다.기존 코드먼저, 기존에 사용하던 NetworkU.. 2024. 7. 8.
[Android/Kotlin] Fragment 전환 시 비동기 처리 문제 해결: OnBackStackChangedListener 사용법 Fragment 전환 시 발생하는 비동기 처리 문제를 해결하기 위해 FragmentManager.OnBackStackChangedListener를 사용하는 방법을 소개합니다.이 글에서는 supportFragmentManager.popBackStack()의 비동기적 특성으로 인해 현재 Fragment를 정확하게 가져오지 못하는 문제를 해결하는 과정을 설명합니다.1. 서론안드로이드 앱 개발 시, 뒤로가기 버튼을 커스터마이징하여 사용자의 편의성을 높이고자 할 때가 있습니다. 특히 Fragment 전환 시 발생하는 비동기 처리 문제를 해결하는 것이 중요합니다. 이번 글에서는 이러한 문제를 해결하기 위해 FragmentManager.OnBackStackChangedListener를 어떻게 활용할 수 있는지 살펴봅.. 2024. 6. 27.
반응형