코틀린 & 컴포즈 & Java 57

컴포즈(compose) 컴포저블 함수 상태 관리

컴포저블 함수 상태 관리 7장에서는 초기화 후에 객체를 ViewModel에 전달하는 방법 객체를 사용해 데이터를 불러오고 저장하는 방법을 알아본다. 상태 유지와 검색 이전에 배운것 컴포즈 앱에서는 상태를 State나 MutableState의 인스턴스로 나타낸다. 상태가 변경됨에 따라 재구성 동작을 유발한다. 상태를 전달 받아 호출한곳으로 상태를 옮기는 것을 상태 호이스팅이라 부른다. 이러한 상태는 종종 사용하는 부모 컴포저블 중 하나에서 기억되는 경우도 있다. → 다른 대안으로 ViewModel 패턴으로 구현하는 방법이 있다. ViewModel 인스턴스는 데이터 초깃값을 어디서 가져오고, 데이터가 변경되면 무슨일을 하게 되는가? 안드로이드에서는 리포지터리 패턴 제안(책에서) 생성 class ViewMod..

컴포즈(compose) 앱 스타일링

컴포즈 앱 스타일링 1 색상, 모양, 텍스트 스타일의 정의 대부분의 컴포즈 UI는 android.compose.material 패키지에 내장된 컴포저블 함수를 사용할 것이다. 브랜드나 회사들은 그들의 정체성을 반영하는 색상, 모양, 텍스트 컬러를 정의하곤 한다. 그렇기 때문에 기본적으로 제공되는 머터리얼 컴포저블 함수의 모양을 수정할 필요가 있다. 머터리얼 테마의 메인 진입점은 MeterialTheme()이다. 이 컴포저블은 커스텀 색상, 모양, 텍스트 스타일을 매개변수로 전달받는다. 값을 설정하지 않으면 그에 상응하는 기본값이 사용된다. @Composable fun ComposeUnitConverterTheme( darkTheme: Boolean = isSystemInDarkTheme(), //isSy..

컴포즈(compose) 컴포저블 함수 상태 관리

컴포저블 함수 상태 관리 상태를 갖지 않는 컴포저블과 상태를 갖는 컴포저블 간의 차이점 이해 언제 어떠한 것을 선택할지 살펴본다. 상태를 갖거나 갖지 않는 컴포저블 함수 이해 상태 : 시간이 흐름에 따라 변하는 데이터 UI는 항상 현재 데이터를 보여줘야만 한다는 것이 중요 따라서 값이 변경되면 반드시 UI에 알려야 함. 옵저버블 타입을 사용 State는 기본 인터페이스로, value라는 이름을 갖는 프로퍼티에 특정 타입의 값을 저장하는 객체인 값 홀더(value holder)를 정의 컴포저블 함수가 실행되는 동안 value가 변경될 때마다 재구성될 것이다. 내부적으로 RecomposeScope 인터페이스가 값의 변경 사항을 구독하고 있을 것이기 때문 값이 변경될 수 있게 하려면 MutableState의 ..

컴포즈(Compose) UI 요소 배치

미리 정의된 레이아웃 사용 고려해야 할 세가지 축 수평(Horizontal) 수직(Vertical) 스택(Stacked) Row() - 가로 Column() - 세로 Box() & BoxWithConstraint() - 콘텐츠를 맨위에 쌓음. CheckBox() - 현재 상태(checked)와 선택하면 호출되는 람다(onCheckedChange)를 받는다 함수 작성시점에 레이블 전달할 수 없다. 대신 CheckBox(), Text()를 Row()안에 포함해 유사한 결과물 만들 수 있다. CheckBoxWithLabel()은 MutableState을 받는다. onCheckedChange 내부에서 값이 변경되면 다른 컴포저블 함수를 재구성해야 하기 때문이다 제약 조건을 기반으로 하는 레이아웃 생성 코드를 단..

컴포즈(Compose) 컴포즈 핵심 원칙 자세히 알아보기

잿팩 컴포즈가 의존하고 있는 핵심 원칙을 검토 컴포저블 함수 자세히 살펴보기 컴포저블 함수의 구성 요소 @Composable 어노테이션을 포함하는 코틀린 함수 컴포즈 컴파일러에 해당 함수가 데이터를 UI로 변환 한다는 것을 알림 코틀린 함수 시그니처 선택 사항인 가시성 변경자(private, protected, internal 또는 public) fun 키워드 함수명 매개변수 목록 또는 선택적 기본값 채택 선택 사항인 반환 타입 코드블록 컴포저블 함수명은 파스칼(PascalCase) 표기법을 사용 대문자로 시작하지만 나머지 문자는 소문자로 나타낸다. 두 단어 이상으로 되어있다면 이름은 명사(Demo) 서술형 형용사를 접두어로 갖는 명사(FancyDemo)여야 한다. 다른 코틀린 함수와는 다르게 컴포저블 ..

컴포즈(Compose) 선언적 패러다임 이해

전통적인 뷰 기반 접근 방식은 컴포넌트와 클래스에 중점을 뒀던 것에 비해 새로운 프레임워크는 선언적 접근 방식을 따른다. 안드로이드 뷰 시스템 살펴보기 기존 접근 방식 컴포넌트 트리를 정의하고 런타임에서 변경하는 것 레이아웃 파일은 계층구조(트리)를 정의 레이아웃 파일 인플레이팅 두가지 문제 변수를 초기화 하기 전에 접근하면 런타임에서 크래시 컴포넌트 개수가 많아지면 코드가 비대해짐 두 번째 문제를 해결하고자, 컴포넌트 참조를 계속 유지해야 하는 작업을 덜어주고자 구글은 뷰 바인딩 기능을 제공 일반적인 UI 프레임워크를 명력적이라고 하는 이유 UI는 XML파일로 정의 UI는 런타임 단계에서 컴포넌트 트리로 인플레이트된다. UI를 변경하려면 연관된 모든 컴포넌트의 속성을 수정해야만 한다. UI 요소가 화면..

컴포즈(Compose) 앱 빌드

젯팩 컴포즈 공부를 시작하였습니다. 책 : 젯팩 컴포즈로 개발하는 안드로이드 UI 안드로이드 개발당시 처음에는 앱이 작았고 소수의 디바이스만 지원하면 됐기 때문에 문제없이 잘 동작했다. 점점 새 기능 및 화면 크기등 폼 팩터가 각각 다르게 출시되며 복잡성이 급격히 증가. 대부분의 문제는 명령적 접근 방식 Ui툴킷 방식에서 발생. 해결책은 패러다임을 전환하는 것. 웹 프레임워크 : 리액트 (선언적 접근 방식) 플러터 또는 SwiftUI도 뒤 따랐다. 잿팩 컴포즈는 구글이 안드로이드용으로 만든 선언적 UI 프레임워크다. 코틀린 전용 컴포저블 함수와 인사 @Composable fun Welcome() { Text( text = stringResource(id = R.string.welcome), style =..

코틀린(Kotlin) - 고차함수 흐름제어 forEach

forEach에서 return시 원하는 동작대로 되지 않아 작성하였습니다. 람다 안에서 return시 어떻게 되는지 살펴보자. 람다 안의 return문 : 람다를 둘러싼 함수로부터 반환 람다 안에서 return을 사용하면 람다뿐만 아니라 그 람다를 호출하는 함수의 실행을 끝내고 반환됩니다. 자기 자신을 둘러싸고 있는 블록보다 더 바깥에 있는 블록을 반환하는 return 문을 넌로컬(non-local) return 이라고 부릅니다. -> onClick함수가 끝난다. return이 바깥쪽 함수를 반환시킬 수 있는 경우는 람다를 인자로 받는 함수가 인라인 함수인 경우뿐입니다. 인라이닝 되지 않는 함수에 전달되는 람다 안에서는 return을 사용할 수 없다. -> 람다를 변수에 저장하거나 바깥쪽 함수를 반환한 ..

인라인 함수: 람다의 부가 비용 없애기

인라인 함수: 람다의 부가 비용 없애기 람다가 변수를 포획하면 람다가 생성되는 시점마다 새로운 무명 클래스 객체가 생긴다. 이런경우, 실행 시점에 무명 클래스 생성에 따른 부가 비용이 든다. → 똑같은 작업을 수행하는 일반 함수를 사용한 구현보다 덜 효율적 inline 변경자 컴파일러는 그 함수를 호출하는 모든 문장을 함수 본문에 해당하는 바이트 코드로 바꿔치기 해준다. 작동 방식 함수를 호출하는 코드를 함수를 호출하는 바이트코드 대신에 함수 본문을 번역한 바이트 코드로 컴파일한다. [Kotlin in Action 책] p.365 8.13~8.3 synchronized 함수의 본문뿐 아니라 전달된 람다의 본문도 함께 인라이닝 된다. 함수 타입의 변수를 넘길수도 있다. fun runUnderLock(bod..

고차 함수 정의

고차 함수 (High order function) 다른 함수를 인자로 받거나 함수를 반환하는 함수 함수 타입 val sum: (Int, Int) -> Int = { x, y -> x+y } val action: () -> Unit = { println(42) } 함수 타입을 정의하려면 함수 파라미터의 타입을 괄호 안에 넣고, 그뒤에 화살표(→)를 추가한 다음, 반환 타입을 지정하면 된다. 함수타입을 선언할 때는 반환 타입으로 반드시 명시해야 하므로 Unit을 빼먹어서는 안 된다. 반환 타입이 널이 될 수 있는 타입 var canReturnNull: (Int, Int) -> Int? = {x, y -> null} 함수 타입 전체가 널이 될 수 있는 타입 var funOrNull: ((Int, Int) ->..