👩🏻‍💻 Develop 108

[Android / Retrofit] End of input at line 1 column 1 path $

🐛 End of input at line 1 column 1 path $- Retrofit에서 내려오는 응답이 비어있을 경우에 발생하는 에러 각 상황에 따라 2가지 해결방법이 있습니다🔑  1) NullOnEmptyConverterFactory- Retrofit Module에 addConverterFactory에 NullOnEmptyConverterFactory를 추가합니다, 추가하면 빈 응답은 null로 변환하여 반환됩니다 🔑 2) Response (Response에 데이터가 필요 없는 경우 ex) @Delete ) - 응답 값이 필요하지 않는 요청이라면 Response로 선언합니다 - 데이터를 받을 수 없으므로, 받아야하는 경우엔 사용이 적합하지 않습니다

🐛 버그 2024.09.13

[Android] Bitmap crop with Rect

자르려면 필요한 값 자르려는 원본 이미지(bitmap) , 자를 영역의 정보 (좌표 및 크기) Rect(x,y,width,height)자를 영역의 시작 좌표 = x, y자를 영역의 너비,높이 = width, heightval rect = Rect(x, y, width, height)val cropBitmap = Bitmap.createBitmap(자르려는 원본 이미지, rect.left, rect.top, rect.width(), rect.height()) Rect 클래스의 주요 구성 요소좌표 (Coordinates):left: 사각형의 왼쪽 경계top: 사각형의 위쪽 경계right: 사각형의 오른쪽 경계bottom: 사각형의 아래쪽 경계

📱 Android 2024.06.13

[Bug / RecyclerView] java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionNotificationHolder

🐛 SwipeRefreshLayout에서 refresh시 발생 주 원인  : 데이터 변경 시 리사이클러뷰의 뷰 홀더와 실 데이터가 불일치 SwipeRefreshLayout에서 refresh 발생 시 Adapter의 아이템을 clear 하고 새로 그렸는데, 이 과정에서 문제가 발생한 거 같다  시도한 방법 1. bindViewHolder할 때 holder.bind(아이템목록[position])을 holder.bind(아이템목록[absoluteAdapterPosition])으로 변경  -> 똑같이 에러 발생 2. refresh후 데이터 가져올 때 clear()를 시키지 않고, 데이터를 가져온 후 기존의 데이터와 바꿈!  -> 성공 🔑 recyclerView는 기존의 뷰 홀더를 재사용하려고 하지만, cl..

🐛 버그 2024.05.20

이미지 수난기

까먹기 않기 위해 우선 적어두고,, 나중에 다시 정리할 예정입니다 1. clipRect(Rect rect)현재 클립 영역을 지정된 사각형으로 설정합니다.지정된 사각형 내부의 영역만 그려집니다.사각형 외부의 영역은 그려지지 않습니다.2. clipOutRect(Rect rect)현재 클립 영역에서 지정된 사각형 영역을 제외합니다.지정된 사각형 외부의 영역만 그려집니다.사각형 내부의 영역은 그려지지 않습니다. public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height) { throw new RuntimeException("Stub!");}  createScaledBitmap 메서드Android의 ..

📱 Android 2024.05.16

[Android] Glide vs Picasso

이미지 라이브러리 중 가장 유명한 Glide와 Picasso입니다 각각 장단점은 잘 모르고 있었던터라, 한번 조사해봤어요 Glide Glide.with(context) .load(imageUrl) .apply(RequestOptions() .centerCrop() .placeholder(R.drawable.loading_spinner) .diskCacheStrategy(DiskCacheStrategy.ALL)) .into(imageView) 장점 - GIF, webp 지원 - 이미지 로딩 성능이 좋다 - 생명주기와 연동된다 Glide.with(context) context가 Activity / Fragment 에 따라 해당 컴포넌트 생명주기와 연동해 동작합니다 ex) 이미지 로딩이 진행 중인데 컴포넌트들..

📱 Android 2024.03.17

[Android] @IgnoredOnParcel

통신을 위해 model을 설계했는데, 클라이언트에서만 사용하는 변수가 필요한 상황입니다 클라이언트에서만 사용될 값을 추가하는데, 만약 이게 서버 통신에서 쓰인다면.. 아찔한 상황입니다 T_T 이럴 경우엔, IgnoredOnParcel 을 사용합니다 @IgnoredOnParcel - Parcelize annotation이랑 함께 사용되는데 특정 필드가 Parcelable 구현에서 제외시킵니다 즉 Parcelable 인터페이스를 구현할 때 고려되지 않으므로, 인텐트에 데이터를 넘기거나 상태를 저장/복원하는 과정에서 이 변수는 무시되고, 클라이언트 상에서만 사용할 수 있습니다 :) @Parcelize data class User( val name: String, val age: Int, @IgnoredOnPa..

📱 Android 2024.02.25

[kotlin] forEach(람다식)의 return break, continue처럼 사용하기

return 가장 가까운 enclosing function을 return 시킨다 val arr = arrayListOf("A","B","C","D","E","F","G") fun checkForEach() { arr.forEach { if(it == "D") return } println("찍힐까요 안 찍힐까요?") } 위의 예제를 실행하면 어떤 결과가 나타날까? 더보기 checkForEach()를 return 시키므로, println문이 찍히지 않는다 함수내의 lambda식을 return하고 싶다면? return@label 특정 label의 lambda식을 return 한다 val arr = arrayListOf("A","B","C","D","E","F","G") fun checkForEach() { ..

💡 Kotlin 2024.01.05

[Android] fragment - lifecycleOwner / viewLifecycleOwner

Fragment에서 LiveData observe를 사용하면서 아래처럼 LifecycleOwner를 사용하게 되었는데, lifecycleOwner와 viewLifecycleOwner의 차이가 무엇인지에 대해 알아보고자 합니다 LifecycleOwner - 프래그먼트 자체의 생명주기를 갖는 class - fragment가 추가되고, 소멸될때까지의 lifecycle viewLifecycleOwner - 프래그먼트 뷰의 생명주기를 갖는 class - onCreateView~onDestroyView viewLifecycleOwner가 권장되는 이유? Fragment의 lifecycle(앞서 언급했던 lifecycleOwner)는 Fragment View의 lifecycle보다 더 긴 것에 주목해야합니다 만약, ..

카테고리 없음 2023.09.17

[Android] SingleLiveEvent , EventWrapper

SingleLiveEvent : 화면 회전 등 구성요소 변경 시, 이벤트가 여러번 호출되는 걸 방지하기 위해 사용 -> 단일 이벤트 사용 import android.util.Log import androidx.annotation.MainThread import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import java.util.concurrent.atomic.AtomicBoolean class SingleLiveEvent : MutableLiveData() { private val pending = AtomicBoolean(false) @Main..

📱 Android 2023.09.03