import 'package:flutter/material.dart';
/// 温度显示 -- ok
class TemperatureIndication extends StatefulWidget {
final ValueChanged<int> valueChanged;
final int choosedItem;
TemperatureIndication({this.valueChanged, this.choosedItem = 0});
@override
_TemperatureIndicationState createState() => _TemperatureIndicationState();
}
class _TemperatureIndicationState extends State<TemperatureIndication> {
int _choosedItem = 0;
@override
void initState() {
super.initState(); // 错误点在这里
_choosedItem = widget.choosedItem;
print('_TemperatureIndicationState initState:$_choosedItem');
}
@override
Widget build(BuildContext context) {
// _choosedItem = widget.choosedItem;
// print('_TemperatureIndicationState build:$_choosedItem');
return _buildItem();
}
Widget _buildItem() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Column(
children: <Widget>[
_buildTextItem(),
Padding(padding: const EdgeInsets.only(top: 4.0)),
_buildButtonItem(),
],
),
);
}
Widget _buildTextItem() {
return Row(
children: <Widget>[
Expanded(
child: Center(child: Text('切')),
),
Expanded(
child: Center(child: Text('低')),
),
Expanded(
child: Center(child: Text('中')),
),
Expanded(
child: Center(child: Text('高')),
),
],
);
}
Widget _buildButtonItem() {
return DecoratedBox(
decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))),
child: Row(
children: <Widget>[
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_choosedItem = 0;
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(0);
}
},
child: DecoratedBox(
decoration: _choosedItem == 0
? BoxDecoration(
color: Colors.grey,
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_choosedItem = 1;
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(1);
}
},
child: DecoratedBox(
decoration: _choosedItem == 1
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_choosedItem = 2;
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(2);
}
},
child: DecoratedBox(
decoration: _choosedItem == 2
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_choosedItem = 3;
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(3);
}
},
child: DecoratedBox(
decoration: _choosedItem == 3
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
],
),
);
}
}
测试代码:
@override
Widget build(BuildContext context) {
print('父类build问题:$chooseItem');
return Scaffold(
appBar: AppBar(),
body: TemperatureIndication(
valueChanged: (i) {
chooseItem = i;
print('点击选中的值:$chooseItem');
chooseItem = 0;
print('强制更改的值:$chooseItem');
setState(() {});
},
choosedItem: chooseItem,
),
);
}
简单功能:就是把选中的值返回给调用者
问题描述:在返回值函数里,强制把选中的值改为 0,发现没有效果?
结论:按照官网的文档说法,widget会由架构来判断是否会刷新,判断会刷新了才刷新。刚好,我这种写法是被判断为不刷新。
@override
void initState() {
super.initState();
_choosedItem = widget.choosedItem;
print('_TemperatureIndicationState initState:$_choosedItem');
}
问题出在以上代码中。我在State类重新定义了一个属性在initState函数中接收StatefulWidget的属性,导致的出现这样子的问题。
正确的做法是在State的build方法中直接使用StatefulWidget的属性。即是widget.choosedItem在build方法中直接使用。
原因:State的initState只执行了一次,后面StatefulWidget的choosedItem更改了,但是没有再次执行initState方法,导致_choosedItem没有跟着更改。所以界面就不会跟着更改。
结论:StatefulWidget是State的配置文件,在State中直接使用StatefulWidget的属性。
以上代码改为:
import 'package:flutter/material.dart';
/// 温度显示 -- ok
class TemperatureIndication extends StatefulWidget {
final ValueChanged<int> valueChanged;
final int choosedItem;
TemperatureIndication({this.valueChanged, this.choosedItem = 0});
@override
_TemperatureIndicationState createState() => _TemperatureIndicationState();
}
class _TemperatureIndicationState extends State<TemperatureIndication> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return _buildItem();
}
Widget _buildItem() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Column(
children: <Widget>[
_buildTextItem(),
Padding(padding: const EdgeInsets.only(top: 4.0)),
_buildButtonItem(),
],
),
);
}
Widget _buildTextItem() {
return Row(
children: <Widget>[
Expanded(
child: Center(child: Text('切')),
),
Expanded(
child: Center(child: Text('低')),
),
Expanded(
child: Center(child: Text('中')),
),
Expanded(
child: Center(child: Text('高')),
),
],
);
}
Widget _buildButtonItem() {
return DecoratedBox(
decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))),
child: Row(
children: <Widget>[
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(0);
}
},
child: DecoratedBox(
decoration: widget.choosedItem == 0
? BoxDecoration(
color: Colors.grey,
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(1);
}
},
child: DecoratedBox(
decoration: widget.choosedItem == 1
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(2);
}
},
child: DecoratedBox(
decoration: widget.choosedItem == 2
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {});
if (widget.valueChanged != null) {
widget.valueChanged(3);
}
},
child: DecoratedBox(
decoration: widget.choosedItem == 3
? BoxDecoration(
color: Color(0xfffe0007),
)
: BoxDecoration(),
child: Container(
height: 28.0,
),
),
),
),
],
),
);
}
}