Bottom Sheet 내부에 EditText를 넣으면 상황에 따라 상하 컴포넌트나 BottomSheet 윗부분이 화면 영역을 넘어가버려 사용에 불편한 경우가 있습니다.이럴 경우 Bottom Sheet Style에 아래 item을 설정해 주면 됩니다.falseadjustResize 그리고 BottomSheet의 onCreate()에서 아래와 같이 선언해줍니다.setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme)android:windowIsFloating의미: 이 속성은 창이 플로팅(floating) 창인지 여부를 설정합니다. 플로팅 창은 일반적인 Activity 창과는 다르게, 독립된 팝업처럼 동작하며,..
전체 글

앱 자체의 잠금 기능을 구현할 때, 비밀번호 말고도 사용자가 더욱더 빠르게 보안 접근을 해제할 수 있도록 지문 인증 처리를 제공할 수도 있습니다.private var biometricPrompt: BiometricPrompt? = nullprivate var promptInfo: BiometricPrompt.PromptInfo? = null먼저 위 두 개 변수를 선언해 줍니다. BiometricPrompt사용자가 지문, 얼굴 인식 등을 통해 인증을 수행할 때 해당 프롬프트를 표시하고, 인증이 성공하거나 실패했을 때의 콜백을 처리합니다. BiometricPrompt.PromptInfoBiometricPrompt.PromptInfo는 BiometricPrompt에 표시할 다이얼로그의 정보를 구성하는 데 사용..

RxJava 라이브러리를 통해 검색 기능을 구현하는 부분에 대해 다뤄보겠습니다.RxJava를 통해 검색 중에 Reactive Steam으로 사용자가 입력 중인 검색어에 따라 debounce로 실시간 검색 처리가 가능합니다. 먼저 RxJava에 대한 개념 몇 가지를 살펴보자면.. Reactive Programming: 데이터를 비동기 스트림으로 처리하는 프로그래밍 패러다임입니다. 데이터의 흐름을 관찰하면서 이벤트가 발생하면 이를 구독자에게 전달하여 처리하는 방식입니다.Observable: 스트림에서 발생하는 이벤트나 데이터를 발행하는 주체입니다. TextView의 텍스트 변화처럼 연속적인 이벤트를 관찰하고, 이에 대해 구독자에게 이벤트를 전달합니다.Observer: Observable이 발행하는 이벤트나..

기존 프로젝트는 Retrofit을 매번 모든 Api 통신 클래스 하위에 가지고 있었습니다. 또한 통신 과정에서 예외 처리하는 부분까지 반환되는 타입이 매번 다를 뿐 거의 유사했기 때문에코드 관리 및 낭비를 줄이기 위한 정리가 필요했습니다. API 통신 클래스들이 추상 클래스를 상속받는 형태로 처리를 진행했습니다.먼저 각각의 API 통신 결과 타입은 항상 상이할 수 있기에 제네릭을 활용하여 값을 받을 Result Class를 만들어줍니다.sealed class Result { data class Success(val data: T) : Result() data class Error(val message: String? = "ERROR", val code: Int) : Result()}매번 다른 ..

참여하고 있는 개발 커뮤니티에서 기회가 생겨서..부족하지만 발표를 진행했었습니다.사내에 디자인 시스템을 도입하면서 알게 된 디자인 시스템의 개념과 장점, 그와 동시에 Compose를 최초 도입하면서 알게 된 부분들을 개발 분야에 상관없이 다른 분도 이해하실 수 있는 발표를 진행해 봤습니다.이해가 되셨을지는 모르겠으나 ㅎㅎ..;; 몇 가지 주요한 부분들만 올려보자면아토믹 디자인 시스템의 단계적 구성과 그를 각 조합에 맞게 구현한 예시를 보여주는 장면입니다.XML에서 구현한 컴포넌트를 자유롭게 활용하여 조합하고 사용할 수 있습니다. Compose의 개념과 장점, 그리고 컴포즈 내 변수에서 항상 보이는 mutableStateOf()와 remember에 대한 이야기입니다.리컴포지션 개념리컴포지션은 상태가 변경될..

하단 탭 바를 통해 탭을 이동하는 것뿐 아니라 간혹 내부 컴포넌트 onClick을 통해 탭을 이동해야 하는 경우가 있습니다.이때는 NavController를 통해 원하는 탭을 지정할 수 있습니다.FloatingActionButton( onClick = { navController.navigate(Screen.Notes.route) } ...navigate 함수에 탭 key 값을 인자로 넣어줌으로써 지정한 탭으로 이동이 가능합니다. 하지만? 여기서 문제가 한 가지 발생합니다.1번 탭에 있다가 2번 탭으로 navigate -> 이후 다시 하단 탭바로 1번 탭으로 이동하려 하면 1번 탭으로 이동되지 않습니다.이 현상은 NavController가 경로(Route)와 백 스택(Back..

컴포즈에서 하단에 4칸짜리 탭을 구현해 보겠습니다.먼저 gradle에 아래 navigation 의존성 추가가 필요합니다.implementation("androidx.navigation:navigation-compose:2.8.1")implementation("androidx.compose.material3:material3:1.2.1") 탭을 구성하기 위해서는 NavigationBar, NavigationGraph, 각 탭 별 Screen Class가 필요합니다.그리고 화면에서 NavController를 통해 등록된 화면 간의 이동을 제어하게 됩니다. 먼저 필요한 화면에 대한 기본 데이터(route, title, icon....)들을 sealed class로 정의해 줍니다.sealed class Scre..

자사 서비스를 개발하던 중, 대량 데이터를 가지고 있는 특정 사용자의 CS에서 화면에 보여야 할 데이터의 렌더링이 느리다는 보고를 받았습니다.화면을 넘기다가 멈추면 일정이 늦게 그려져요. 서비스의 데이터(일정)를 보여주는 화면의 구조는 ViewPager로 구성되어 있었고, 각 페이지가 Selected 될 때마다 매번 전체 데이터 중 현재 화면에 보여줘야 할 데이터들을 쿼리 하는 작업이 수행되는 구조였습니다.문제점은 빠르게 스크롤을 하면 대량의 쿼리 요청이 축적되고, 데이터 DB는 작업의 부하가 걸리면서 최종적으로 보이는 마지막 페이지의 쿼리 후 데이터 렌더링이 지연되는 것이었습니다. 해결 방안DB 작업을 취소하던지, 순서 제어를 하던지 둘 중 하나의 방법이 필요했습니다.하지만 안드로이드 SQLite에서..

https://www.acmicpc.net/problem/2910[문제]위대한 해커 창영이는 모든 암호를 깨는 방법을 발견했다. 그 방법은 빈도를 조사하는 것이다.창영이는 말할 수 없는 방법을 이용해서 현우가 강산이에게 보내는 메시지를 획득했다. 이 메시지는 숫자 N개로 이루어진 수열이고, 숫자는 모두 C보다 작거나 같다. 창영이는 이 숫자를 자주 등장하는 빈도순대로 정렬하려고 한다.만약, 수열의 두 수 X와 Y가 있을 때, X가 Y보다 수열에서 많이 등장하는 경우에는 X가 Y보다 앞에 있어야 한다. 만약, 등장하는 횟수가 같다면, 먼저 나온 것이 앞에 있어야 한다.이렇게 정렬하는 방법을 빈도 정렬이라고 한다.수열이 주어졌을 때, 빈도 정렬을 하는 프로그램을 작성하시오.첫째 줄에 메시지의 길이 N과 C가..

https://www.acmicpc.net/problem/5648모든 원소가 양의 정수인 집합이 있을 때, 원소를 거꾸로 뒤집고 그 원소를 오름차순으로 정렬하는 프로그램을 작성하세요.단, 원소를 뒤집었을 때 0이 앞에 선행되는 경우는 0을 생략해야 합니다.첫 번째로 입력되는 건 n (1 ≤ n ≤ 106)으로 사용자가 뒤이어 입력할 원소값을 결정합니다. 입력하는 줄에는 하나의 원소값뿐만 아니라 여러 원소값도 들어갈 수 있습니다.단, 입력하는 정수는 1012를 넘어선 안 됩니다.출력문은 위 문제 내용에 나와있는 정렬방법으로 정렬하여 아래 예제 출력을 참고하여 출력하세요. [풀이]문제 자체는 쉽게 이해할 수 있는데, 자잘한 오류가 발생하는 구간들이 있네요.일단 첫 번째로 입력되는 건 사용자가 입력할 원소 개..