🐥
【Jetpack Compose】StateFlow でカウンターを作ってみる
Composable 入れ子の更新具合を確認します。
@HiltViewModel
class SampleViewModel @Inject constructor() : ViewModel() {
private val _count = MutableStateFlow(0)
val count = _count.asStateFlow()
fun inc() {
_count.update { count -> count + 1 }
}
}
@Composable
fun SampleScreen(
viewModel: SampleViewModel = hiltViewModel()
) {
val count: Int by viewModel.count.collectAsState()
Column(
Modifier.fillMaxSize(),
Arrangement.Center,
Alignment.CenterHorizontally
) {
Text("$count")
Button(onClick = { viewModel.inc() }) {
Timber.d("Button composed.")
Icon(Icons.Filled.Add, null)
}
}
}
何回クリックしても Button の compose は一回。
Button composed.
Button 内に影響される Text() を追加する。
@Composable
fun SampleScreen(
viewModel: SampleViewModel = hiltViewModel()
) {
val count: Int by viewModel.count.collectAsState()
Column(
Modifier.fillMaxSize(),
Arrangement.Center,
Alignment.CenterHorizontally
) {
Text("$count")
Button(onClick = { viewModel.inc() }) {
Timber.d("Button composed.")
Icon(Icons.Filled.Add, null)
Text("$count") // *
}
}
}
クリックするたびに、Button は compose される。
Button composed.
Button composed.
Button composed.
Button composed.
Button composed.
Button composed.
...
ネストした Composable
@Composable
fun SampleScreen(
viewModel: SampleViewModel = hiltViewModel()
) {
val count: Int by viewModel.count.collectAsState()
Column(
Modifier.fillMaxSize(),
Arrangement.Center,
Alignment.CenterHorizontally
) {
Text("$count")
ChildA(onClick = { viewModel.inc() })
ChildB(count, onClick = { viewModel.inc() })
}
}
@Composable
fun ChildA(onClick: () -> Unit) {
Button(onClick = onClick) {
Timber.d("ChildA composed.")
Icon(Icons.Filled.Add, null)
}
}
@Composable
fun ChildB(count: Int, onClick: () -> Unit) {
Button(onClick = onClick) {
Timber.d("ChildB composed.")
Icon(Icons.Filled.Add, null)
Text("$count")
}
}
ChildA は初回のみ compose されます。 ChildA、ChildB どちらのボタンを押しても re-compose されるのは、ChildB のみです。
D: ChildA composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
D: ChildB composed.
...
無駄な描画をしない!
すごいです、Jetpack Compose!!
ただ、カウンター程度なら Flow を使うまでもないが。
👉 JakeWharton/timber: A logger with a small, extensible API which provides utility on top of Android's normal Log class.
👉 Jetpack Compose State Guideline. This article presents the information… | by takahirom | Medium
👉【Jetpack Compose】Icon() や Image() で ImageVector をより便利に使う
Discussion