Compose Code Style
https://itstory1592.tistory.com/74
[Android] Jetpack Compose Part 1 - Does and Dont Code Style #1
https://github.com/tmdgh1592/Jetpack-Compose-Android-Examples GitHub - tmdgh1592/Jetpack-Compose-Android-Examples: Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Com Learn Jetpack Compose for Android by Examples. Learn how to use J
itstory1592.tistory.com
https://itstory1592.tistory.com/75
[Android] Jetpack Compose Part 1 - Does and Dont Code Style #2
https://github.com/tmdgh1592/Jetpack-Compose-Android-Examples GitHub - tmdgh1592/Jetpack-Compose-Android-Examples: Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Com Learn Jetpack Compose for Android by Examples. Learn how to use J
itstory1592.tistory.com
https://kotlinlang.org/docs/coding-conventions.html
Coding conventions | Kotlin
kotlinlang.org
컴포즈 코드 스타일에 방황하다가, 잘 정리된 글이 있어서 공유해본다!
SingleTons, Constants, Sealed Class, Enum Class
기존에 상수나 Enum 클래스를 작성할때 CAPITAL_AND_UNDERSCOPES 방식을 선호했음
컴포즈에서는 PascalCase를 사용하도록 권장함
const val PascalCase = "pascal_case"
val PascalCase = 0
object PascalCase {}
sealed class PascalCase {}
enum class PascalCase { Pascal, Case }
@Composable 네이밍
보통 함수 네이밍시, 소문자로 시작하여 PascalCase로 작성했었고, 명사가 아닌 동사로 시작하는 경우가 많았음
ex) fun writeText()
@Composable 함수를 만들때는 대문자로 시작하며 동사보단 명사를 사용하기 권장함
네이밍에 형용사가 들어가는 경우, 명사 앞에 형용사를 작성해주어어 함
@Composable
fun FancyButton() {}
@Composable
fun BackButtonHandler() {}
val LocalTheme = staticCompositionLocalOf<Theme>()
@Composable 값을 반환하는 함수 네이밍
코틀린 네이밍 컨벤션을 따르라고 명시되어 있음
위에서는 대문자, 명사로 시작하라 했으면서, 왜 또 소문자야 할 수 있음 -> 위에서 다룬 컴포즈 함수는 화면을 직접적으로 그리는 함수이지만, 현재 다루는 함수는 값을 반환해주는 함수이기 때문임
@Composable
fun defaultStyle(): Style {}
객체를 반환하는 함수 네이밍
코루틴 스코프와 같은 객체를 반환하는 함수는 rememberAObject() 같은 방식으로 네이밍 하자
createAObject(), makeAObject() 같은 네이밍이 있는데, 컴포즈에서는 remember~로 통일하고자 하는 것 같음
@Composable
fun rememberCoroutinesScope(): CoroutineScope {}
Emit XOR return a value
@Composable 함수는 컨텐츠를 컴포즈를 컴포지션으로 내보내거나, 값을 반환하지만 이 두가지를 동시에 해선 안됨
@Composable
fun InputField(inputState: InputState) {
...
val inputState = remember { InputState() }
Button("clear input", onClick = { inputState.clear })
InputField(inputState)
...
}
@Composable
fun InputField(): UserInputState {
...
Button("clear input", onClick = {})
val inputState = InputFiled()
...
}
Compose UI API structure
Compose UI 는 Compose 런타임에 빌드된 UI 도구 키트임
@Composable
fun SimpleLabel(
text: String,
modifier: Modifier = Modifier
) {}
Element는 Unit을 반환함
Element는 @Composable Annotaion이 붙은 UI 구성요소
요소는 emit()을 호출하거나 다른 Compose UI 요소 함수를 호출하여 루트 UI 노드를 직접 방출해야함 (값을 방출해선 안됨)
Element는 Compose UI 구성의 선언적 엔티티이기 때문 -> 컴포지션에서의 존재 여부에 따라 UI 에 표시되는 여부가 결정되기 때문에 값을 반환하지 않음
Element에 대한 이벤트 처리를 해야한다면, 매개변수를 통해 이벤트 제어 관련 함수나 객체를 입력받도록 하자
@Composable
fun FancyButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {}
Element는 Modifier 파라미터를 입력받으라고 함
Modifier의 경우, Compose UI Element내에서 파라미터의 defaultValue로 값을 지정해주거나, 외부에서 입력받을 수 있음
외부에서 입력을 받으면 중복되는 Element 속성들을 통일화 하여 보일러플레이트 코드를 줄일 수 있고, 외부에서 조작하기에 유리함
@Composable
fun FancyButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) = Text (
text = text,
modifier = modifier.surface(elevation = 4.dp)
.clickable(onClick)
.padding(horizontal = 32.dp, vertical = 16.dp)
)
Compose UI layouts
하나 이상의 @Composable 함수 매개변수를 허용하는 Compose UI 요소를 레이아웃이라고 함
Composable 안에 Composable을 넣어서 레이아웃을 만들 수 있음
이때 매개변수의 이름은 "content" 로 작성하고, kotlin의 후행 람다 구문을 사용 할 수 있도록 @Composable 함수 매개변수를 마지막에 배치하자
@Composable
fun SimpleRow(
modifier: Modifier = Modifier,
conent: @Composable () -> Unit
) {}
Compose UI modifier
modifier는 immutable이기때문에 임의로 수정하는 것은 불가능
modifie는 factory 패턴으로 설계되어 있고, 화면의 속성을 지정할 수 있는 Modifier actory functions를 제공함
Modifier.preferredSize(50.dp)
.backgroundColor(Color.Blue)
.padding(10.dp)
Modifier APIs는 Modifier.Element 인터페이스 implementation type을 노출해선 안됨
fun Modifier.myModifier(
param1: ...,
param2: ...
): Modifier = then(MyModifierImple(param1, param2)
Composed modifiers
Modifier.composed {} 를 사용하면 Modifier에 여러 다른 Modifier를 함꼐 사용할 수 있음
fun Modifier.myModifier(): Modifier = composed {
val color = LocalTheme.current.specialColor
backgroundColor(color)
}
fun Modifier.modifierWithState(): Modifier = composed {
val elementSpecificState = remember { MyModifierState() }
MyModifier(elementSpecificState)
}
val modifier = someModifiers.modifierWithState()
Text("hello", modifier = myModifier)
Text("world", modifier = myModifier)
Layout-scoped modifiers
Android의 View 시스템에는 LayoutParams라는 개념이 있음 (ViewGroup의 자식보기와 함께 불투명하게 지정된 객체 유형으로, 이를 측정하고 배치할 ViewGroup에 특정한 레이아웃 지침을 제공함)
Compose UI 수정자는 레이아웃 콘텐츠 기능에 대해 ParentDataModifier 및 수신기 범위 개체를 사용하여 관련 패턴을 제공함
@Stable
interface WeightScope {
fun Modifier.weight(weight: Float): Modifier
}
@Composable
fun WeightedRow(
modifier: Modifier = Modifier,
content: @Composable WeghtScope.() -> Unit
) {}
WeightedRow {
Text("hello", Modifier.weight(1f))
Text("world", Modifier.weight(2f))
}