Open3
【SwiftUI / Jetpack Compose】ビューのライフサイクルについて調べる
概要
- SwiftUIとJetpack Composeそれぞれについて、描画のライフサイクルについて実験する
親の状態に変化があったとき、親・子のビューはどう変化するか?
SwiftUI
- 変化する状態自体を保持している親ビューは、再構築されない
- 子ビューは、変化する状態を参照している・いないにかかわらず再構築される
コード
struct ContentView: View {
@State private var count = 0
init() {
print("ContentView init \(count)")
}
var body: some View {
VStack {
Text("ContentView: \(count)")
Button("increment") {
count += 1
print("=== ContentView Button Pressed ===")
}
Spacer().frame(height: 30)
ChildCountView(count: count)
Spacer().frame(height: 30)
ChildNoCountView()
}
}
}
struct ChildCountView: View {
let count: Int
init(count: Int) {
self.count = count
print("ChildCountView init \(self.count)")
}
var body: some View {
VStack {
Text("ChildCountView \(count)")
}
}
}
struct ChildNoCountView: View {
init() {
print("ChildNoCountView init")
}
var body: some View {
VStack {
Text("ChildNoCountView")
}
}
}
Jetpack Compose
- 状態を保持する親と、状態を参照する子のComposableが再コンポーズされる
- 状態を参照していない子は再コンポーズされない
コード
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LifecyclelearningTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
ContentView()
}
}
}
}
}
@Composable
fun ContentView() {
var count by remember { mutableStateOf(0) }
println("ContentView() called: $count")
Column {
Text(text = "ContentView $count")
Button(onClick = {
count++
println("=== ContentView Button Pressed ===")
}) {
Text("increment")
}
Spacer(modifier = Modifier.height(30.dp))
ChildCountView(count)
Spacer(modifier = Modifier.height(30.dp))
ChildNoCountView()
}
}
@Composable
fun ChildCountView(
count: Int
) {
println("ChildCountView() called: $count")
Column {
Text(text = "ChildCountView $count")
}
}
@Composable
fun ChildNoCountView() {
println("ChildNoCountView() called")
Column {
Text(text = "ChildNoCountView")
}
}
SwiftUIのViewのidentityについて
Explicit Identity
- 明示的にViewにidentityを付与し、identityを変更するとViewが再構築される。
コード
struct ContentView: View {
@State private var id = 1
init() {
print("ContentView init")
}
var body: some View {
VStack {
ChildView()
.id(id)
Button("increment id") {
id += 1
print("=== increment id ===")
}
}
}
}
struct ChildView: View {
init() {
print("ChildView init")
}
var body: some View {
Text("ChildView")
}
}