분류 전체보기 29

[안드로이드] 스크롤이 가능한 탭 커스텀 뷰

구글에서는 material 디자인 컴포넌트를 지원하고 있다. 이러한 컴포넌트의 장점은 '적은 코드로 많은 기능을 구성할 수 있다' 이다. 대표적으로 TabLayout이 그 예이다. TabLayout은 Viewpager와 연동도 가능하며 Tab 자체에 스타일 xml이나 코드로 커스텀할 수 있어 Tab UI에 많이 사용된다. 하지만 내가 만든 것이 아니라 material 디자인 컴포넌트 규칙을 따라야할 때는 커스텀하기가 영 힘든 일이다. 불편한 거 내가 처음부터 커스텀해보지 해서 이번에 ScrollTablayout을 만들어 보았다. ScrollTabLayout ScrollTabLayout의 결과물을 보면 TabLayout과 거의 흡사하다. 다만 여기서 tab의 디자인이라던가 텍스트 폰트 등은 쉽게 커스텀할 ..

Android/Custom View 2022.12.29

[안드로이드] 클린 아키텍처(Clean Architecture) Mapper 클래스 그게 필요해?

Mapper 클래스란? 클린 아키텍처 3 계층 중에 데이터 계층에 속한 클래스로 서버나, Room과 같은 로컬에서 받아온 데이터 모델과 UI/UX에 맞는 데이터 모델로 매핑하는 클래스 클린 아키텍처(Clean Architecture)를 프로젝트에 적용하면서 mapper 클래스의 기능, 사용성, 정의 등에 대해 고민을 한 적이 있다. 팀 내에서 반대 의견은 데이터 계층에 데이터 모델을 두지 말고 도메인 계층에 데이터 모델을 두면 되는데 왜 관리포인트 두 개를 만들면 오히려 유지보수 측면에서 비효율적이지 않은가였다. 처음에는 어?! 그런가..?라고 생각했지만 클린 아키텍처 협의 세미나 때 다음 아래와 같은 장점 및 정의를 제시하고 이에 팀원들이 동의해서 mapper 클래스 사용을 하기로 하였다. 프로젝트가 ..

[안드로이드] 귀찮니즘이 만들어 준 contains() 함수 응용

이번 프로젝트에서 웹에서 내려주는 link, url, scheme, javainterface을 가지고 앱에서 동작을 분기하거나 특정 페이지를 보내야 하는 작업을 하였다. param, host, scheme 같은 경우에는 Uri.parse()를 통해서 getQueryParmeter, scheme, host를 사용하면 되지만 단순 문자열 포함 체크 시에는 contains()를 사용한다. 하지만 각 웹 팀마다 대문자, 소문자 규칙이 달라서 contains() 함수에서 분기 처리가 잘못되는 버그가 발생하였다. 따라서 각 팀끼리 합의하에 모두 대문자로 치환 후 포함 체크를 하자고 해서 uppercase()를 사용하였다. 대문자 치환을 위해서 반복되는 uppercase() 함수 사용은 귀차니즘을 발동시켰다. 귀차니..

개발 이모저모 2022.12.20

시작일부터 종료일 표현해보기

개발을 하면서 어떠한 정보의 시작일과 종료일 표시를 해야할 때가 있다. 대부분은 시작일 및 종료일을 각각 시간날짜 데이터를 받아 SimpleDateFormat을 사용해서 원하는 형태(yyyy-MM-dd, yyyy.MM.dd)로 표현한다. // 20221225 val format1 = SimpleDateFormat("yyyyMMdd") // 20221225 val format2 = SimpleDateFormat("yyyy.MM.dd") 만약 여기서 아래와 같은 조건이 추가된 유틸 함수를 한번 만들어 보았다. 시작일과 종료일의 년도가 같을 경우 종료일의 년도는 yyyy에서 앞에 두개 yy를 제거(2022 -> 22) 시작일과 종료일의 년도가 다를 경우 시작일, 종료일 모두 년도 표시 시작일과 종료일이 같으면..

개발 이모저모 2022.12.15

Kotlin DSL (2) - Groovy DSL에서 Kotlin DSL로 이관

Kotlin DSL로 이관해야 할 Gradle 목록 앱 레벨 build.gradle 프로젝트 레벨 build.gradle settings.gradle 이관 순서는 정해져있지는 않지만 경험상 모듈 레벨 아래와 같은 순서로 작업하면 수월하다. 모듈 레벨 build.gradle 프로젝트 레벨 build.gradle settings.gradle build.gradle 확장자 수정 build.gradle 파일명에.kts를 붙여 아래와 같이 확장자를 변경한다. build.gradle -> build.gradle.kts settings.gradle -> settings.gradle.kts 확장자를 변경하게 되면 아래 스크린샷과 같이 build.gradle 아이콘이 변경된 것을 확인 할 수 있다. 안드로이드 스튜디오 ..

Android 2022.12.13

Kotlin DSL (1) - Kotlin DSL이란 무엇인가?

Android 개발에서는 Java, Kotlin을 사용하고 있다. 하지만 익숙함 속에서 하나를 놓친 것이 있을 것이다. 이는 바로 Gradle에서 사용하고 있는 Groovy라는 언어(?)를 사용한다. Groovy가 뭐야라고 할 수 있지만 Android Studio에서 프로젝트를 생성시에 만들어지는 build.gradle, settings.gradle이 Groovy로 작성되어 있다. apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' android { compileSdkVersion 31 defaultConfig { applicationId "com.example.codehong" ..

Android 2022.12.13

안드로이드 스튜디오 Arctic Fox 버전 이후 gradle allprojects 오류 해결 방법

나만의 라이브러리를 jitpack으로 배포해서 개인 프로젝트에 적용해보았다. jitpack으로 배포한 라이브러리는 프로젝트 단위의 build.gradle에 allprojects를 추가해야 한다. 이전 프로젝트 단위의 build.gradle에서 allprojects 적용 방법 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } 하지만 Arctic Fox 버전 이후에서는 에러가 발생하면서 빌드가 되지 않았다. Arctic Fox 버전 이후부터는 settings.gradle에 추가해야 한다. Arctic Fox 버전 이후 settings.gradle에 allprojects 적용 방법 dependencyResolutionManageme..

Android 2022.02.05

[차근차근 RxJava 기록 5] Observable을 생성하는 연산자

Observable으ㄹ 생성하는 연산자로는 defer, empty, never, interval, range, timer 연산자가 있다. defer 연산자 defer 연산자는 옵서버가 구독할 때까지 Observable의 생성을 지연시킨다. subscrbie() 메소드를 호출할 때 Observable 아이템을 생성한다. empty, never 연산자 아이템을 발행하지 않는 공통점이 있지만 never 연산자는 onComplete() 호출을 해야 종료가 된다는 차이점이 있다. Observable.empty() .doOnTerminate { Log.d(TAG, "empty 종료") } .subscribe() Observable.never() .doOnTerminate { Log.d(TAG, "never 종료")..

Android/RxJava 2022.01.24

[차근차근 RxJava 기록 4] Cold Observable과 Hot Observable

Cold Observable Observable에 구독을 요청하면 아이템을 발행하기 시작한다. 해당 아이템은 임의의 종료시키지 않는 이상 여러 번 요청하여도 처음부터 끝까지 발행하는 것을 보장한다. val src = Observable.interval(1, TimeUnit.SECONDS) src.subscribe { value -> System.out.println("#1: " + value) } Thread.sleep(3000) src.subscribe { value -> System.out.println("#2: " + value) } Thread.sleep(3000) // #1: 0 // #1: 1 // #1: 2 // #1: 3 // #2: 0 // #1: 4 // #2: 1 // #1: 5 //..

Android/RxJava 2022.01.24

[차근차근 RxJava 기록 3] 다양한 형태의 Observable

Single Observable과 다르게 단 하나의 아이템만 발행한다. 따라서 just() 연산자는 하나의 인자만 가질 수 있다. Single.just("Hello World") .subscribe(System.out::println) create() 연산자를 사용 시에는 데이터를 한 번만 발행하므로 onNext()와 onComplete()을 호출하는 대신 onSuccess(T)을 호출한다. 오류 같은 경우에는 onError() 호출하는 것은 동일하다. Single.create { emitter -> emitter.onSuccess("Hello") }.subscribe(System.out::println) Observable -> Single Observable에서 Single로 변환하는 방법으로는 al..

Android/RxJava 2022.01.21