对比 Flutter Widget 和 Jetpack Compose 来解释:
1. StatelessWidget - 类似 Compose 中的无状态组件:
// Flutter - StatelessWidget
class GreetingCard extends StatelessWidget {
final String name;
const GreetingCard({required this.name});
@override
Widget build(BuildContext context) {
return Card(
child: Text('Hello, $name!'),
);
}
}
// Compose 对应写法
@Composable
fun GreetingCard(name: String) {
Card {
Text("Hello, $name!")
}
}
特点:
- 像纯函数一样,输入相同则输出相同
- 不保存状态
- 适合展示静态内容
2. StatefulWidget - 类似 Compose 中使用 remember 的组件:
// Flutter - StatefulWidget
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () {
setState(() {
count++;
});
},
child: Text('Increment'),
),
],
);
}
}
// Compose 对应写法
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column {
Text("Count: $count")
Button(onClick = { count++ }) {
Text("Increment")
}
}
}
特点:
- 可以保存和更新状态
- 状态改变时会重建 UI
- 适合交互性组件
3. 实际应用场景:
// Flutter - 购物车商品项
class CartItem extends StatelessWidget {
final String name;
final double price;
final String image;
const CartItem({
required this.name,
required this.price,
required this.image,
});
@override
Widget build(BuildContext context) {
return ListTile(
leading: Image.network(image),
title: Text(name),
subtitle: Text('\$$price'),
);
}
}
// Compose 对应写法
@Composable
fun CartItem(
name: String,
price: Double,
image: String
) {
ListItem(
leadingContent = {
AsyncImage(model = image)
},
headlineText = { Text(name) },
supportingText = { Text("$${price}") }
)
}
4. 带状态的实际例子:
// Flutter - 可编辑的个人资料
class EditProfile extends StatefulWidget {
@override
_EditProfileState createState() => _EditProfileState();
}
class _EditProfileState extends State<EditProfile> {
String name = '';
String bio = '';
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
onChanged: (value) {
setState(() {
name = value;
});
},
decoration: InputDecoration(
labelText: 'Name',
),
),
TextField(
onChanged: (value) {
setState(() {
bio = value;
});
},
decoration: InputDecoration(
labelText: 'Bio',
),
),
ElevatedButton(
onPressed: () {
// 保存资料
},
child: Text('Save'),
),
],
);
}
}
// Compose 对应写法
@Composable
fun EditProfile() {
var name by remember { mutableStateOf("") }
var bio by remember { mutableStateOf("") }
Column {
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") }
)
OutlinedTextField(
value = bio,
onValueChange = { bio = it },
label = { Text("Bio") }
)
Button(onClick = { /* 保存资料 */ }) {
Text("Save")
}
}
}
5. 生命周期对比:
// Flutter - StatefulWidget 生命周期
class LifecycleWidget extends StatefulWidget {
@override
_LifecycleWidgetState createState() => _LifecycleWidgetState();
}
class _LifecycleWidgetState extends State<LifecycleWidget> {
@override
void initState() {
super.initState();
// 初始化,类似 Compose 的 SideEffect
}
@override
void dispose() {
// 清理,类似 Compose 的 DisposableEffect
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
// Compose 对应写法
@Composable
fun LifecycleDemo() {
DisposableEffect(Unit) {
// 初始化
onDispose {
// 清理
}
}
}
总结:
-
StatelessWidget vs 无状态 Composable:
- 都是纯展示组件
- 依赖外部传入的数据
- 不维护内部状态
-
StatefulWidget vs 有状态 Composable:
- 都可以维护内部状态
- Flutter 使用 setState
- Compose 使用 remember 和 mutableStateOf
-
主要区别:
- Flutter 分离状态和 UI(State 类)
- Compose 状态和 UI 在一起
- Flutter 更面向对象
- Compose 更函数式
-
使用建议:
- 优先使用 StatelessWidget/无状态组件
- 需要状态时才用 StatefulWidget/状态组件
- 合理拆分组件
- 状态下沉,UI 上浮
-
性能考虑:
- StatelessWidget 更轻量
- 状态改变范围要合理
- 避免不必要的重建
- 适当使用缓存