Android 36

Preference Datastore

언제 쓸까?로그인 세부 정보 저장, 다크모드 설정, 글꼴 크기 등 작고 간단한 데이터 세트에 적합대용량 or 복잡한 데이터 → Room을 쓰자.  Jetpack DataStore 라이브러리 → 데이터 저장을 위한 간단하고 안전한 비동기Preference DataStore : key-value로 저장Proto DataStore : 프로토콜 버퍼를 사용하여 스키마 정의 → Strong Type 데이터 유지 가능Proto DataStore는 type safety, 효율적이지만 구성과 설정이 필요함Preference DataStore는 쉽게 설정 가능  필수 추가 종속성implementation("androidx.datastore:datastore-preferences:1.0.0")implementation("..

Android 2024.04.25

구글 권장 앱 아키텍처

Clean : UI → Domain ← Data Google : UI → Domain(optional) → Data UI Layer UI 레이어 : 화면에 애플리케이션 데이터를 표시 사용자 상호작용 또는 외부 입력으로 인해 데이터가 변할 때마다 변경사항을 반영하도록 UI가 업데이트 돼야함. UI Element + UI State = UI State를 활용해서 UI를 나타내줘야함 우수 사례 data class NewsUiState( val isSignedIn: Boolean = false, val isPremium: Boolean = false, val newsItems: List = listOf(), val userMessages: List = listOf() ) data class NewsItemUiS..

Android 2024.04.19

Android Jetpack Comopse의 CompositionLocal을 이해하고 써보자

왜 나온걸까?Composable 함수는 Tree구조를 가지고 있다.이때, 상태(state)는 일반적으로 최상단 노드에 저장이 되어있어야 한다(상태 호이스팅)상위 트리에서 만든 상태를 하위 트리에서 매개변수로 받는 것이 아닌, 바로 접근할 수 있게 해준다.  왜 최상단에 저장되어있어야 할까?컴포넌트들은 상태를 모르는게 좋다. 최상단에서 전달해준 정보를 바탕으로 화면을 나타내는 것이 더 좋은 방법이라고 생각한다. 왜냐하면 상태를 컴포넌트 별로 다 가지고 있다면 이후 추적하는 것도 힘들고, 각각의 상태를 하나씩 참조하며 변경해줘야 하기 때문에 관리하기 더 어려워 진다. 그렇다면 상태가 최상단에 있고, 트리 개념으로 아래로 내려가는 UI 구조를 가진다고 했는데 “매번 변수로 state를 내려줘야..

패키지 이름이 중복일때 해결하는 방법 :(

android 개발을 할때 가장 마주치고 싶지 않은 상황중 하나인 패키지명을 수정하는 상황을 만났을 때 해결방법을 소개하고자 한다. 패키지명을 바꾸는 경우는 아래와 같다고 생각한다. 1. 패키지에 example이 있는 경우 - play스토어에 올리기 위해서는 com.example.~~~으로 시작하면 안된다. 어떻게 알았냐구요? 알고싶지 않았어요.... 2. 패키지명이 중복된 경우 - play스토어에 이미 같은 패키지가 올라가있는 경우 게시가 불가능하다. 이것도 직접 겪은 감동실화다... 예전에 작업할 때는 수정하는 방법을 몰라서 파일 전체를 날리고 다시 만드는 일을 한 적이 있다. 그때 공부해둔 방법을 이번에 프로젝트를 진행하며 적용하게 되었다. 수정할 당시 너무 긴장해서 스크린샷은 못찍었습니다 ㅎㅎ....

Android 2024.01.15

Coil이 항상 옳을까? Coil vs Glide

왜 이 주제를 선택했을까? 얼마전 당근에 다니고 계시는 선배님과 잠깐 전화로 이야기를 나눌 일이 있었다. 내 이력서를 보시고 다양한 코멘트 들을 해주셨는데 그 중 “내가 사용하는 기술에 대한 명확한 근거가 있어야 한다”라는 내용이 있었다. 그 이야기를 듣고 생각해보니 난 그저 관습적으로 늘 쓰던 기술을 사용한 것 뿐이지 왜 그 기술을 사용 했는지에 대한 명확한 근거가 없었다. 그래서 내가 사용하는 기술과, 그 대체재를 찾아보고 명확한 근거를 수립하여 이후 프로젝트에서 사용할 기술을 정하고자 한다. 이번 글에서 비교해볼 주제는 “이미지 로딩 라이브러리”이다. Coil이란? Coil은 Kotlin Coroutines로 만들어진 Android 백엔드 이미지 로딩 라이브러리로, Cououtine Image Lo..

RecyclerView와 SnapHelper - SnapHelper 커스텀

아래 두 동영상의 차이점이 뭘까? 왼쪽은 각 항목들이 호롤롤로롤로로 힘없이 넘어간다. 반면 오른쪽 동영상은 한칸씩 딱! 딱! 맞춰서 넘어간다. 이걸 구현하기 위해서 대부분은 ViewPager를 사용할 것이다. 이 상황에서는 맞는 방법이다. 하지만 이런 UI라면? Grid처럼 한 페이지에 여러 값이 존재하고, 그게 한칸씩 딱딱 맞춰서 넘어가야한다. 그리고 중요한점. 가운데 정렬이 아닌, 왼쪽 정렬이다 이거땜에 개빡쳤었다. 💡 이럴때는 ViewPager를 쓰는것도 나쁘지 않지만, RecyclerView도 활용해보자. 왜 굳이 ViewPager를 안쓰고 RecyclerView를 쓸까? 구현하기가 너무 귀찮았다그래서 RecyclerView를 Grid레이아웃으로 작성하고, Custom해서 VIewPager효과를 ..

Exception과 runCatching

Exception이란? 쉽게 말해서 error다. 제일 흔한 예시로 NullPointerException, ArrayIndexOutOfBoundsException 등등이 있을 것이다. 그럼 exception은 발생하면 안되는 걸까? 물론 정상적으로 작성된 코드에서는 발생하면 안되는게 맞다. 하지만, 개발자가 의도적으로 exception을 발생시킬 때가 있다. 왜 발생시킬까? 개발자가 의도하지 못한 상황이 발생하거나, 안드로이드 앱이 종료되는 것을 막기 위해 의도적으로 에러를 발생시켜 핸들링 하기 위해서로 알고있다. 틀렸거나, 더 명확한 이유가 있다면 댓글로 알려주세용 ㅎㅎ 어떻게 발생시킬까? throw라는 것을 활용해서 의도적으로 exception을 발생시킨다. private fun getUserInfo..

[Jetpack Compose] Button 사용법의 모든것

Button 말 그대로 버튼을 화면에 나타내고자 할 때 사용된다. Button(onClick = { /*TODO*/ }) { Text(text = "Button") } 어우 많다. 하나씩 가보자. onClick 버튼을 클릭했을 때 발생시킬 액션이다. api를 호출시킬 수도 있고, Toast를 띄울 수도 있고 페이지를 이동시킬 수도 있다. 그냥 버튼 클릭시 실행시키고 싶은 모든것을 넣으면 된다. enabled Button( onClick = { /*TODO*/ }, enabled = false ) { Text(text = "Button") } 버튼을 활성화시킬지 여부를 나타낸다. 기본값은 true이고, false로 설정하면 버튼이 클릭되지 않는다. 그럼 이건 어떨때 쓸까? 난 최근에 썼을때 입력받은 정보..

[Jetpack Compose] Text 사용법의 모든것

Text 말 그대로 텍스트를 화면에 나타내고자 할 때 사용된다. class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { SOPTComposeStudyTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Text(text = "Hello World!") } } } } } Text도 Composable 함수이기 때문에 매개변수들을 살펴보자.오… 많다. 하나씩 하나씩 뽀개보자. text..

[Jetpack Compose] LaunchedEffect란?

LaunchedEffect가 뭘까? 코루틴을 사용하기 위한 suspend function을 호출하기 위해 필요하다. 좀 더 쉽게 말하자면 중간에 멈추고자 하는 함수를 넣기 위해서 존재한다. 이게 무슨소린가 싶을거다. 이전에 내가 작성한 Delay함수 관련 글이 있다. 이것처럼 도중에 멈추고 싶을때 LaunchedEffect를 사용한다. https://naemamdaelo.tistory.com/entry/Jetpack-Compose-%08Delay-%EC%A3%BC%EB%8A%94-%EB%B0%A9%EB%B2%95 [Jetpack Compose] Delay 주는 방법 개발을 하다보면 특정 초 지난 후 에 기능이 작동하면 좋겠다는 생각을 할 때가 있다. 그러면 Delay를 줘야하는데 어떻게 줄 수 있을까?..