在有状态窗口小部件中调用setState会将窗口小部件的类型更改为父级的类型。为什么会发生这种情况,有什么方法可以防止这种情况发生?
在提供的示例中,更改Slider值将调用setState来重建小部件。通过覆盖didUpdateWidget
,可以看到没有任何反应,并且该小部件仍然是同一小部件。但是,覆盖==
表明Slider Widget类型从Container更改为Slider。
输出:
Runtime Type Old: Container New: SliderWidget
预期输出:
Runtime Type Old: SliderWidget New: SliderWidget
为什么会这样?
代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("Text Widget"),
SliderWidget(),
],
),
),
);
}
}
class SliderWidget extends StatefulWidget {
SliderWidget({Key key}) : super(key: key);
@override
_SliderWidgetState createState() => _SliderWidgetState();
@override
bool operator ==(other) {
print("RuntimeType Old: ${other.runtimeType} New: $runtimeType");
return this.runtimeType == other.runtimeType;
}
@override
int get hashCode => runtimeType.hashCode;
}
class _SliderWidgetState extends State<SliderWidget> {
int value = 10;
@override
void didUpdateWidget(SliderWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
@override
Widget build(BuildContext context) {
return Container(
child: SliderTheme(
data: SliderThemeData(
showValueIndicator: ShowValueIndicator.always,
),
child: Slider(
value: value.toDouble(),
min: 0,
max: 100,
label: value.toString(),
onChanged: (double value) {
setState(() {
this.value = value.toInt();
});
},
),
),
);
}
}
演示: