컴포즈에서는 특정 영역에서만 호출할 수 있는 함수 형태를 많이 사용한다.
예를 들면 BoxScope
, ColumnScope
, RowScope
등의 영역 안에서만 호출할 수 있는Modifier.align
, Modifier.weight
등이 있다.
확장함수를 통해서 해당 영역에서만 사용할 함수들을 추가할 수 도 있는데,
문제가 있다.
interface CustomScope {
val value: Int
fun Modifier.scopeModifier(): Modifier
}
// 불가능
fun CustomScope.Modifier.newScopeModifier(): Modifier {
return this
}
CustomScope 같은 영역에다가 새로운 Modifier를 추가하고 싶을 때,
확장함수에다가 또 확장함수는 붙일수가 없다.
interface ModifiedCustomScope : CustomScope {
fun Modifier.newScopeModifier(): Modifier
}
class ModifiedCustomScopeImpl(customScope: CustomScope) : ModifiedCustomScope , CustomScope by customScope{
override fun Modifier.newScopeModifier(): Modifier {
return this
}
}
CustomScope 가 내가 가지고 있는 코드라면 CustomScope 안에다가 Modifier를 추가하면 되지만
BoxScope, ColumnScope 같이 라이브러리에 포함되어 있는 형태라면
결국 새로운 Modifier 하나를 추가하기 위해 Scope 를 상속받는 새로운 Scope를 만들고,
delegation을 통해서 이전의 Scope도 연결해줘야 한다.
context receivers 사용하기
kotlinOptions {
jvmTarget = '1.8'
freeCompilerArgs = ["-Xcontext-receivers"]
}
gradle에 명시하여 활성화할 수 있다.
context receivers는 함수에다가 적용시킬 수 있고,
적용된 함수는 해당 context 내에서만 호출할 수 있도록 제한을 걸어준다.
이걸 이용하면 위의 문제를 해결할 수 있다.
interface CustomScope {
val value: Int
fun Modifier.scopeModifier(): Modifier
}
context(CustomScope)
fun Modifier.contextModifier(): Modifier {
Log.d("D000l", value.toString())
return this
}
context
를 이용하면 해당 함수가 CustomScope 안에서만 사용할 수 있도록 제한된다.
CustomScope에 있는 값도 바로 접근하는 것이 가능하다.
this로 접근이 필요한 경우 this@CustomScope
처럼 가능하다.
(타이핑시에 this@CustomScope는 자동 완성이 안된다. 아직 실험기능이라 그런 듯 )
context(Context, Int)
fun getStringFromStringRes(){
this@Context.getString(this@Int)
}
val appName = with(R.string.app_name){
getStringFromStringRes()
}
여러 개의 context를 적용할 수도 있기 때문에 확장함수로 풀어내기 애매했던 부분들에 유용하게 사용할 수 있다.
'안드로이드' 카테고리의 다른 글
KotlinDl - Android 물건탐지, 동작탐지 등등 (0) | 2022.12.19 |
---|---|
안드로이드 라이브러리 관리 자동화 (1) | 2022.11.15 |
Android - BuildSrc + Version Catalog ( 안드로이드 버전 관리하기 ) (0) | 2022.11.15 |
Android - Module Graph 그리기 (0) | 2022.11.13 |
Compose - Modifier.Node ( composed 상위호환 ) (0) | 2022.11.08 |