Android 75

안드로이드 권한 정리

카메라 쓴다고 카메라 권한 넣고 이미지 쓸거라고 권한 넣는게 아니다. 이 권한을 언제 사용해야 하고 하지 말아야하는지 정리해보자. 1. 이미지 피커 단순 이미지만 불러오는 경우 권한 필요없음, 시스템 이미지 피커를 사용하면 됨 private val callbackImageContracts = registerForActivityResult(ActivityResultContracts.PickMultipleVisualMedia(EXTRA_MAX_IMAGE)) { uris -> if (uris != null && uris.isNotEmpty()) { viewModel.sendImages(uris) } } -> 구글에서 만든 세련된 BottomSheet 이미지 피커가 뜸 이미지 피커 UI를 커스텀 하는 경우 권한..

Android 2023.06.02

RecyclerView Drag & Drop

ItemTouchHelper.Callback 이용하여 아이템 드래그&드랍을 구현하려고 한다. 이때 실무에 적용하기 위해 ListAdapter, 뷰모델과 연동하여 리스트 싱크까지 맞춘 방법으로 정리 일단 기본 방법으로 구현하면 LongClick 일때 드래그가 시작된다. (ItemTouchHelper.Callback 내부 구현) class ItemTouchHelperCallback( private val moveListener: ItemMoveListener ) : ItemTouchHelper.Callback( ) { override fun getMovementFlags( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { ret..

Android 2023.05.18

영상URL에서 샘플 이미지 가져오기 ( 코일 )

영상 URL로부터 샘플 이미지를 가져와서 로드하는 방법 glide는 영상 URL 도 인식하여 메타데이터에서 샘플 이미지를 가져올 수 있다. 하지만 coil은 ImageLoader를 커스텀해야한다. 해당 프로젝트에서는 coil을 사용하였으므로 가능하다면 변경하고 싶지 않았다. 기본 지식 1. coil 라이브러리는 단순히 load()를 사용하면 내부에서 만들어진 ImageLoader 객체를 사용한다. 2. 바인딩 어댑터와 같이 사용할때 아래와 같이 함수로 정의하여 사용한다. @BindingAdapter( value = [ "src", "placeholder" ], requireAll = false ) fun ImageView.bindSrc( src: Any?, placeholder: Drawable? = n..

Android 2023.02.21

FlowBinding 사용하여 코드 간소화

flowbinding 이란? View의 이벤트 연결을 Flow, Flow 로 변형해주는 라이브러리 사용 이유? 코드 간소화 및 중복클릭방지 처리, flow의 장점 이용 가능 소셜 로그인시 각 버튼마다 이벤트를 연결해야 하는 경우 아래와 같은 코드를 apple.setOnClickListener { viewModel.login(AuthType.APPLE) } google.setOnClickListener { viewModel.login(AuthType.GOOGLE) } kakao.setOnClickListener { viewModel.login(AuthType.KAKAO) } naver.setOnClickListener { viewModel.login(AuthType.NAVER) } facebook.setO..

Android 2023.01.11

QR코드 스캔 커스텀 ( + 플래시 )

QR 코드 스캔시 아래 화면과 같이 커스텀 - 기본 UI에서 세로로 지정하기 세로로 지정하기에 대한 구글링 해보면 아래와 같이 나온다. ( 하지만 이렇게 하는건 비효율적이라고 생각함. 왜 굳이 쓸모없이 액티비티를 만드는건데? ) 1. 새로운 액티비티를 만들고 class CustomCaptureActivity : CaptureActivity() 2. 해당 액티비티로 captureActivity를 지정하고 captureActivity = CustomCaptureActivity::class.java 3. 해당 액티비티의 screenOrientation 속성을 portrait 나 fullSensor로 명시 Q. 일단 왜 가로로 나오는가? - 우리가 사용해야할 CaptureActivity가 이렇게 되어있기 때문이..

Android 2023.01.04

[CI/CD] fastlane : App Distribution + Slack Message

fastlane로 아래의 명령어만으로 Firebase DEV, RELEASE 배포 + SLACK 메시지 전송까지 하는 방법을 정리 fastlane distribute ( 2~3일동안 fastlane 만 팠다.. ) 자세한 fastlane 설치 및 환경 설정은 생략함 fastlane 설치 -> 프로젝트에서 init 하여 파일들 초기화 ( git init 같다고 보면 됨 ) 사용할 플러그인 gem 'fastlane-plugin-firebase_app_distribution' gem 'fastlane-plugin-android_versioning_kts' 프로젝트 모듈에 release_note 파일, .env파일 생성 구조를 정리하면 project app fastlane fastfile .env release..

Android 2022.11.24

코루틴 좋아요 동기화 처리

사용자가 컨텐츠에 대해 좋아요 했을때 컨텐츠가 보이는 어떤 화면에서든 이벤트를 받아와 UI 업데이트 하려고 한다. 1. 도메인 모듈에 인터페이스 모델 추가 sealed interface ContentEvent { data class AddLike( val id: Int ) : ContentEvent data class RemoveLike( val id: Int ) : ContentEvent } 레포지토리에 SharedFlow 생성 interface ContentRepository { val contentEvent: SharedFlow } internal class ContentRepositoryImpl @Inject constructor( private val remote: ContentRemoteDat..

Android 2022.11.07

build.gradle에 정의한 manifestPlaceholders 값 주입 받기

build.gradle.kts 에 정의한 manifestPlaceholders을 코틀린 파일에서도 사용할수 있도록 리팩토링 하기 manifest에서도 사용하고 코틀린 파일에서도 사용하는 빌드 변수가 있다. 카카오 로그인시 (KAKAO_APP_KEY) 1. 메니페스트에 명시 2. SDK 초기화 KakaoSdk.init(this, "${KAKAO_APP_KEY}") 문제점 buildConfigField로 정의하면 코틀린에서만 사용가능하고 manifestPlaceholders로 정의하면 manifest에서만 사용가능하다. 기존 방법 manifestPlaceholders["KAKAO_APP_KEY"] = "aaaaaaaaaaaaa" aaaaaaaaaaaaa 똑같은걸 2번 정의하여 사용하였다. ( string...

Android 2022.11.05

카카오톡 채팅화면 키보드 옵션창 구현

카카오톡 채팅화면의 키보드와 옵션창 구현 내용 정리 개발 과정 1. 레이아웃 구성 2. 로직 적용 3. 부드러운 모션 적용 1. 레이아웃 구성 채팅 리사이클러뷰 하단에 height="0dp"로 옵션창 추가 ( 이게 하단 옵션 창 ) 2. 로직 적용 기본 세팅 WindowInsets을 사용하기 위해 시스템 Inset을 제거 한다. ( 내가 컨트롤 할 예정 ) override fun onCreate(savedInstanceState: Bundle?) { WindowCompat.setDecorFitsSystemWindows(window, false) super.onCreate(savedInstanceState) } 그리고 키보드가 올라왔을때와 시스템바에 대한 패딩을 준다 ( 전체 레이아웃 root에 ) Vie..

Android 2022.10.09

Gson으로 sealed class 로 맵핑하기

https://yuar.tistory.com/entry/API-Response-Map-%ED%98%95%ED%83%9C%EB%A1%9C-%EB%B0%9B%EA%B8%B0 context.deserialize( params, Context.Params.A::class.java ) params.has("result") -> context.deserialize( params, Context.Params.B::class.java ) else -> null } } } 일단 요기에서 json은 Param 객체를 지칭한다 ( 위에서 Param 객체를 만나면 이 클래스를 타라고 정의 했으니 ) json을 jsonObject ( gson 객체 ) 로 변환하고 해당 객체가 count 를 가졌는지, result 를 가졌는지에..

Android 2022.10.04