CompositionLocalとは
公式リファレンス: https://developer.android.com/develop/ui/compose/compositionlocal
Composeのバケツリレーでメソッドに値の受け渡しが不要になります
AndroidCompositionLocalsでもすでに便利な定義がされています
AndroidCompositionLocals.android.kt
/**
* The Android [Configuration]. The [Configuration] is useful for determining how to organize the
* UI.
*/
val LocalConfiguration = compositionLocalOf<Configuration> {
noLocalProvidedFor("LocalConfiguration")
}
/**
* Provides a [Context] that can be used by Android applications.
*/
val LocalContext = staticCompositionLocalOf<Context> {
noLocalProvidedFor("LocalContext")
}
internal val LocalImageVectorCache = staticCompositionLocalOf<ImageVectorCache> {
noLocalProvidedFor("LocalImageVectorCache")
}
/**
* The CompositionLocal containing the current [LifecycleOwner].
*/
val LocalLifecycleOwner = staticCompositionLocalOf<LifecycleOwner> {
noLocalProvidedFor("LocalLifecycleOwner")
}
/**
* The CompositionLocal containing the current [SavedStateRegistryOwner].
*/
val LocalSavedStateRegistryOwner = staticCompositionLocalOf<SavedStateRegistryOwner> {
noLocalProvidedFor("LocalSavedStateRegistryOwner")
}
/**
* The CompositionLocal containing the current Compose [View].
*/
val LocalView = staticCompositionLocalOf<View> {
noLocalProvidedFor("LocalView")
}
独自の値を設定することも可能
SharedPreferencesなどいちいち定義するのが面倒なものもここに設定することでCompose側からならどこでも利用できるようになります
SampleTheme.kt
@Composable
fun SampleTheme(
content: @Composable () -> Unit
) {
val preferences = LocalContext.current.getSharedPreferences("prefs", Context.MODE_PRIVATE)
CompositionLocalProvider(
LocalPreferences provides preferences
) {
MaterialTheme(
content = content
)
}
}
val LocalPreferences = staticCompositionLocalOf<SharedPreferences> {
error("error hogehoge")
}
メリット
- 無駄なバケツリレー回避
- 子コンポーネントのみ定義のオーバーライドをすることも可能
- コンポーネントの再利用性の向上
デメリット
- 可視性が低いため、複数の子コンポーネントで値の変更をしすぎるとデバッグ困難、コードの難読化が発生
- 過剰利用によるアーキテクチャの崩壊
- 大きなComposeツリーで利用することによるパフォーマンスの低下
おわり
あくまでもこれはComposableで使うものに限定することを強くおすすめします!
きれいなコード、きれいな設計を一発で台無しにする可能性を孕んでいるものです
用法用量を守って正しくお使いください