[Android] 수제 ImageViewer(feat. Coil) (Compose)
·
Android
먼저, 이미지를 로딩하는 라이브러리로는 🔗Coil을 사용했다.implementation("io.coil-kt.coil3:coil-compose:{latest version}")implementation("io.coil-kt.coil3:coil-network-okhttp:{latest version}")ImageViewer의 기능은 다음과 같다.이미지를 표시두 손가락으로 확대/축소1배수 미만으로 축소하면 손가락을 뗐을때 1배수크기/정위치로 원복확대한 상태에서 이미지 위치를 이동확대한 상태에서 이미지 위치를 이동하고 손을 뗐을 때, 화면 가장자리에서 이미지가 떨어지면 위치를 되돌림더블 탭 하면 이미지를 1배수크기/정위치로 원복확대 후 이미지 이동 시, 이미지가 화면 밖을 넘어가지 않도록 함import ..
[Android] 멀티모듈에서 gradle의 BuildType 공통화
·
Android
현재 어떤 프로젝트를 멀티모듈로 개발하고 있다. BuildType을 `debug`/`staging`/`release`로 나누려고 했는데, 생각해보니 거의 모든 모듈에 같은 BuildType 정의를 써줘야 한다는 문제를 마주쳤다. 모든 build.gradle에 일일히 BuildType을 써줘야 한다..? 분명 공통화 방법이 있을 것이라고 생각하여 시작하게 됐다. 목표1. BuildType 코드를 한군데로 빼서 공통화 2. 현재 BuildType마다 달라지는 변수 설정. 그런데 BuildConfig를 쓰지 않고. 이 두가지 목표를 이룰려고 한다 BuildType 공통화`build-logic` 모듈 만들기참고로 스튜디오의 파일은 Project 모드로 보고있습니다. 공통된 하나의 BuildType 정..
[Android] java.lang.ClassCastException
·
Android
androidx.constraintlayout.widget.ConstraintLayout$LayoutParams cannot be cast to android.widget.LinearLayout$LayoutParams이것은 단순히 `View`에 `LayoutParams`을 `set`할 때 부모 레이아웃 타입의 `LayoutParams`를 사용하지 않아서 발생하는 Exception이다. 그런데 디버깅을 하면서 알아낸 것이 있어서 기록해놓는다. visibility가 `GONE`인 `View`는 해당 Exception이 발생하지 않는다. 실제로 화면에 그려질 때 발생하는듯 싶다. `try-catch`로 잡히지 않는다.실제로 화면에 그려질 때 발생하는 것으로 짐작했을 때, `setLayoutParams` 메..
[Android] Compose TextField 커스텀
·
Android
만들고 싶었던 것MaterialDesign이 적용되지 않은 `TextField`width가 입력되어있는 텍스트 길이 만큼 wrapCotent할 것Placeholder 표시결과는 아래와 같다. 붉은 글씨 부분이 placeholder를 표시하고있는 `TextField`임구현 과정1. MaterialDesign이 없는 TextField일반적인 `TextField` 컴포저블을 사용하면 MaterialDesign을 피할 수 없기 때문에, 아무 디자인도 적용되지 않은 `BasicTextField`를 사용해야 한다.BasicTextField( value = text, onValueChange = { onTextChange(it) }, ...)호출하면 기본 width를 가지는 텅빈 `TextF..
[Android] LazyColumn안에 LazyVerticalGrid 넣기(nested scroll)
·
Android
전제 조건LazyColumn안에 LazyVerticalGrid가 들어감LazyVerticalGrid의 정확한 height는 몰라도 예상하는 최대 height 값이 있어야 함최대 height값을 어떻게든 지정할 수 없다면 이 방법은 사용할 수 없습니다.. 본인은 화면 중간에 LazyVerticalGrid가 들어가고, 표시해야 하는 데이터의 최대 개수가 정해져 있었기 때문에 해당 방법이 가능했다. 방법 거창한건 아니고... LazyColumn 안에 height가 지정되지 않은 LazyVerticalGrid를 집어넣게 되면 height를 제대로 측정하지 못해서 넣을 수가 없는 것이기 때문에 최대 height라도 지정을 해주면 정상적으로 동작한다.LazyColumn( modifier = Modif..
[Kotlin] Flow를 StateFlow로 변환
·
Kotlin
`stateIn`으로 `Flow`를 `StateFlow`로 변환하는 것에 대한 간단한 이해를 정리한 글 Flow `Flow`는 cold 스트림해당 플로우에 대해서 `collect`가 호출되기 전까지는 아무런 동작 하지 않음`collect`가 호출되면 처음부터 발행값 발행이 완료되면 스트림이 종료됨val myFlow = flow { // collect가 호출되기 전까지 // 해당 코드는 실행되지 않음 // 0부터 100까지 1초 간격으로 값을 발행(emit) repeat(100) { Log.d(TAG, ">> emit -> $it") emit(it) delay(1000) }}CoroutineScope(Dispatchers.Main).laun..
[Android] Retrofit2 Multipart사용하기 (Java)
·
Android
글을 쓸 당시에는 직접 구현했던 것을 토대로 작성했는데, 현재는 그럴 수가 없어 업데이트를 하지 못했습니다. 변경사항이 있다고 하니 유의 바랍니다.MultipartRetrofit2을 통해 서버로 파일을 전송할 때 사용하게 된다. 아마 다음과 같은 형태로 인터페이스를 정의할 것이다.@Multipart@POST("api주소")Call request(파라미터들...);파일 전송때문에 Multipart 어노테이션이 붙어서, 그냥 보낼 수 있는 타입도 Multipart에 맞게 보내야 했던 것 같다. 왜그랬는지 기억은 안나는데, file 전송할 때 자꾸 안돼서 이것저것 계속 시도했었던 것 같다. 일단 내 경우에 성공적으로 동작했던 방법을 정리한다. file이 아닌 것단일 항목한개만 보내면 되는 경우, `..
[Android] RecyclerView와 ListAdapter (Java)
·
Android
🔗RecyclerView https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView?hl=ko🔗RecyclerView 릴리즈 노트 https://developer.android.com/jetpack/androidx/releases/recyclerview?hl=ko🔗ListAdapter https://developer.android.com/reference/android/widget/ListAdapter?hl=enListAdapter ListAdapter는 RecyclerView에 쓸 수 있는 어댑터이다. 기존의 어댑터와는 다르게 DiffUtil을 사용하여 비동기식 처리를 할 수 있다. 기존의 기본 어댑터는..