Android
[Android, Kotlin] Bottom Navigation View + Jetpack Navigation 바텀 메뉴 클릭 시 프래그먼트 재생성 막기
문제 : 위 사진(카카오톡)과 같이 바텀 메뉴 클릭 시 최초 클릭 시에는 프래그먼트가 생성되어 화면이 로딩되고, 이후 클릭 시에는 기존 생성된 프래그먼트가 유지되었으면 한다. 그러나 기본적인 Jetpack Navigation + Bottom Navigation View의 경우에는 바텀 메뉴를 클릭 할 때마다 프래그먼트가 재생성된다. 1 - 최초 생성 2 - 한번 더 BookFragment 바텀 메뉴 클릭 3 - 다른 바텀 메뉴로 갔다가 다시 BookFragment 메뉴 클릭 위와 같이 어떤 경우에서든지 메뉴를 클릭하기만 하면 해당 메뉴와 연결된 프래그먼트가 재생성된다. 1 - 최초 생성의 경우에만 프래그먼트가 생성되고, 2와 3의 경우에는 기존 프래그먼트를 hide - show 하는 방향으로 하여 카카오..
[Android, Kotlin] Firebase DB에서의 각 Listener별 차이점 (Value, Single, Child)
Firebase Realtime DB를 사용 할 때, 리스너를 등록하여 DB 내 값이 변경 될 때마다 해당 변경 사항을 동기화시켜 리사이클러뷰 등의 리스트를 업데이트 할 일이 잦다. 이 때 등록 할 수 있는 리스너는 3가지 종류가 있다. 1. ValueEventListener 2. SingleValueEventListener (DatabaseReference.addListenerForSingleValueEvent(ValueEventListener) 형태로) 3. ChildEventListener 리스너를 사용 중 각 리스너 별 동작에 따른 차이점과 사용 형태가 궁금해져 직접 3가지 형태의 리스너를 달고 데이터가 추가 되었을 때의 결과를 확인해보았다. 먼저, 초기에 구성되어 있는 기본 DB 상태이다. "U..
[Android, Kotlin] ClipboardManager를 사용하여 기기에서 복사된 값 붙여넣기
문제 : 택배 조회를 위해 운송장 번호를 입력해야 한다. 이 때, 휴대폰에서 복사한 운송장 번호를 자동으로 붙여넣기 할 수 있는 기능을 추가해야 한다. (Dialog를 통해 붙여넣기 여부 확인) 해결 : 휴대폰에서 복사한 값에 대한 처리는 클립보드(clipboard)에서 담당한다. 클립보드(clipboard) : '종이 끼우개' 라는 뜻으로, 잘라내기(복사) / 붙여넣기를 통해 문서 또는 응용프로그램 사이에서 자료가 전송 될 때 짧은 시간동안 해당 값을 저장하는 데에 사용되는 소프트웨어 프로그램 우리는 이 클립보드에서 사용자가 복사 (또는 잘라내기) 한 값을 꺼내서 해당 값의 유효성을 확인 한 후, 붙여넣을지 여부를 확인 할 것이다. Android, Kotlin에서는 클립보드의 값을 꺼내오기 위해 Cli..
[Android, Kotlin] sortedWith()와 compareBy()를 사용한 collection의 다중 정렬 기준 설정
문제 : 등록한 운송장 리스트의 배송 상태가 업데이트 될 때, 업데이트 된 배송 상태에 따라 리스트의 정렬이 필요했다. 다음과 같은 형태의 데이터를 가지는 TrackingInfoCompany 객체의 List를 정렬해야 한다. data class TrackingInfoCompany { val completeYN: String, // 배송완료 시 "Y", 아니면 "N" val time: Long // 마지막 업데이트 시간 (millisecond 단위) } 정렬 기준은 다음과 같다. 1. 배송 완료의 경우, 업데이트 시간에 관계 없이 가장 인덱스의 뒤에 위치. (배송 완료 상태의 값끼리는 업데이트 시간 최근 순으로 인덱스 앞 위치) 2. 업데이트 시간이 최근 순으로 인덱스의 앞에 위치. 해결 : 이를 해결하기..
[Android, Kotlin] RecyclerView에서 스크롤 시 Check box의 check 상태 보존
배경 : "편집" 버튼 클릭 시, RecyclerView의 각 Item 왼쪽에 선택 할 수 있는 체크 박스가 나온다. 문제 : 체크 후, RecyclerView 스크롤 시 체크의 상태가 보존되어 있지 않는다. 기존 코드 : // ViewHolder의 bind 메소드 fun bind(info: TrackingInfoCompany) { val position = bindingAdapterPosition.takeIf { it != NO_POSITION } ?: return binding.information = info binding.checkBox.isVisible = modifyMode binding.checkBox.isChecked = getItem(position).isChecked binding.ch..
[Android, Kotlin] Bottom Navigation View + Jetpack Navigation 사용 시 fade animation 제거
Bottom Navigation View와 Jetpack Navigation을 함께 연결하여 사용하게 되면, 자동적으로 탭 간 전환에서 fade animation이 적용된다. fade amination도 괜찮지만 UX 측면에서 탭 간 전환에 답답함을 느낄 수도 있을 것 같아 이를 제거하고자 하였다. 기본으로 지정되어 있는 애니메이션을 수정하기 위해 아래 경로에 해당 코드를 넣어 애니메이션을 제거한다. 주의 할 점은, 일반적으로 사용하는 anim이 아닌, animator 디렉토리에 저장해야한다. res/animator/nav_default_enter_anim.xml res/animator/nav_default_exit_anim.xml res/animator/nav_default_pop_enter_anim...
[Android, Kotlin] Custom Dialog 만들기
만들게 된 이유 : 앱 기능 중 Shared Preference를 이용하여 초기 프로필 이름 설정이 존재. 해당 Dialog를 커스텀하게 만들기 위해. 결과물 : rounded corner + 커스텀 레이아웃으로 다이얼로그를 꾸몄다. 코드 : // dialog_radius_background.xml dialog의 corner radius를 위한 background xml을 구성한다. : 사각형 shape : corner radius(둥글기) 30dp 지정 : background color white // dialog_edittext_background.xml dialog에 들어가는 EditText의 background xml을 구성한다. : 두께 2dp의 테두리 선 , 색상 black // dialog_..
[Android, Kotlin] Room DB에서 Flow를 사용하여 DB 변경 observing
조건 : 찜한 글 목록에서 글 클릭 -> 클릭한 글의 detail 화면에서 찜 해제 시 DB에서 찜한 글 목록이 바로 업데이트 됨 -> 다시 찜한 글 목록으로 돌아왔을 때 업데이트 된 찜한 글 목록이 나오도록 해야 함. 문제 : 다시 찜한 글 목록으로 돌아왔을 때 찜한 글이 update되지 않음. // FavoritePostViewModel.kt val posts: StateFlow = favoriteRepository.getAllPosts() .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5000), initialValue = Result.Uninitialized ) ViewModel에서는 Repository에서 g..
[Android, Kotlin] Coroutine Flow block 내에서 여러 개의 suspend function에 대한 비동기 처리
조건 : retrofit을 활용한 api 통신을 수행하는 2개의 suspend function을 통해 flow block에서 댓글 목록과 글쓴이의 정보를 가져와 PostInfo 객체로 wrapping 하여 emit해야 함. 발생한 문제 : 2개의 suspend function으로 인해 각 suspend function이 끝날 때 까지 해당 flow block이 suspend되므로 연관이 없는 api 통신임에도 불구하고 동기적으로 수행되어 api 통신 속도가 느려짐. 이로 인해 function 시작부터 comments, user를 emit하는 데까지 걸리는 시간은 평균 1.2 ~ 1.3초가 소요됨. 해결 : 처음에는 두 flow를 합치는 zip 연산자를 통해 두 api 연산을 asFlow로 flow로 변환..
[Android, Kotlin] ViewPager2의 currentItem 설정이 동작하지 않는 문제
원하는 동작 : ImageListFragment에서 RecyclerView의 이미지 리스트 중 하나를 클릭하면 클릭한 이미지의 Position을 받아와 GalleryFragment에서 ViewPager 형태로 해당 이미지를 보여준다. ViewPager2의 current position을 이미지의 position으로 설정한다. 발생한 문제 : current position 설정과 관계 없이 리스트의 첫번째 이미지가 보여진다. 기존 코드 : // RecyclerViewBinding.kt @JvmStatic @BindingAdapter("submitListViewPager") fun bindSubmitListViewPager(view: ViewPager2, list: Array) { (view.adapter ..