setState 不更新 wiget UI
setState does not update wiget UI
我花了几个小时试图理解为什么单击 IconButton 不会切换更改其图标。
import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
@override
_TestIconChangeState createState() => _TestIconChangeState();
}
class _TestIconChangeState extends State<TestIconChange>
with TickerProviderStateMixin {
IconData _iconData = Icons.add;
AnimationController _animationController1;
Widget _child;
@override
void initState() {
super.initState();
_animationController1 = AnimationController(
vsync: this,
value: 1,
duration: Duration(seconds: 1),
);
}
@override
Widget build(BuildContext context) {
if (_child == null) _child = _buildButton();
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 100),
child: _child,
),
RaisedButton(
child: Text('Text Child'),
onPressed: (() {
setState(() {
_child = Text('Dummy text');
});
}),
),
RaisedButton(
child: Text('Button Child'),
onPressed: (() {
setState(() {
_child =_buildButton();
},);
}),
)
],
),
),
),
);
}
Widget _buildButton() {
return IconButton(
onPressed: () {
setState(() {
(_iconData == Icons.add)
? _iconData = Icons.remove
: _iconData = Icons.add;
});
},
icon: Icon(_iconData),
);
}
}
当您调用 setState
时,它只会重建在 build
方法中构建的小部件。
主要问题是你没有做。您没有在 build
方法中重建 _child
。
你代码中的这一行是错误的:if (_child == null) _child = _buildButton();
如果你这样做 _child = _buildButton();
则只能使用按钮 +/-,但不能更改为文本。需要重构您的代码!
因此,我对您的代码进行了重构,并添加了 ChildType
以指示您要显示的 Widget 类型:文本或按钮。然后在 setState
方法中使用它。现在可以正常使用了,如您所料:)
import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
@override
_TestIconChangeState createState() => _TestIconChangeState();
}
enum ChildType {text, button}
class _TestIconChangeState extends State<TestIconChange>
with TickerProviderStateMixin {
ChildType curChildType = ChildType.button;
IconData _iconData = Icons.add;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 100),
child: _buildButton(),
),
RaisedButton(
child: Text('Text Child'),
onPressed: (() {
setState(() {
curChildType = ChildType.text;
});
}),
),
RaisedButton(
child: Text('Button Child'),
onPressed: (() {
setState(() {
curChildType = ChildType.button;
},);
}),
)
],
),
),
);
}
Widget _buildButton() {
if (curChildType == ChildType.text) {
return Text('Dummy text');
}
else {
return IconButton(
icon: Icon(_iconData),
onPressed: () {
setState(() {
_iconData = (_iconData == Icons.add) ? Icons.remove : _iconData = Icons.add;
});
},
);
}
}
}
祝你好运!
我花了几个小时试图理解为什么单击 IconButton 不会切换更改其图标。
import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
@override
_TestIconChangeState createState() => _TestIconChangeState();
}
class _TestIconChangeState extends State<TestIconChange>
with TickerProviderStateMixin {
IconData _iconData = Icons.add;
AnimationController _animationController1;
Widget _child;
@override
void initState() {
super.initState();
_animationController1 = AnimationController(
vsync: this,
value: 1,
duration: Duration(seconds: 1),
);
}
@override
Widget build(BuildContext context) {
if (_child == null) _child = _buildButton();
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 100),
child: _child,
),
RaisedButton(
child: Text('Text Child'),
onPressed: (() {
setState(() {
_child = Text('Dummy text');
});
}),
),
RaisedButton(
child: Text('Button Child'),
onPressed: (() {
setState(() {
_child =_buildButton();
},);
}),
)
],
),
),
),
);
}
Widget _buildButton() {
return IconButton(
onPressed: () {
setState(() {
(_iconData == Icons.add)
? _iconData = Icons.remove
: _iconData = Icons.add;
});
},
icon: Icon(_iconData),
);
}
}
当您调用 setState
时,它只会重建在 build
方法中构建的小部件。
主要问题是你没有做。您没有在 build
方法中重建 _child
。
你代码中的这一行是错误的:if (_child == null) _child = _buildButton();
如果你这样做 _child = _buildButton();
则只能使用按钮 +/-,但不能更改为文本。需要重构您的代码!
因此,我对您的代码进行了重构,并添加了 ChildType
以指示您要显示的 Widget 类型:文本或按钮。然后在 setState
方法中使用它。现在可以正常使用了,如您所料:)
import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
@override
_TestIconChangeState createState() => _TestIconChangeState();
}
enum ChildType {text, button}
class _TestIconChangeState extends State<TestIconChange>
with TickerProviderStateMixin {
ChildType curChildType = ChildType.button;
IconData _iconData = Icons.add;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 100),
child: _buildButton(),
),
RaisedButton(
child: Text('Text Child'),
onPressed: (() {
setState(() {
curChildType = ChildType.text;
});
}),
),
RaisedButton(
child: Text('Button Child'),
onPressed: (() {
setState(() {
curChildType = ChildType.button;
},);
}),
)
],
),
),
);
}
Widget _buildButton() {
if (curChildType == ChildType.text) {
return Text('Dummy text');
}
else {
return IconButton(
icon: Icon(_iconData),
onPressed: () {
setState(() {
_iconData = (_iconData == Icons.add) ? Icons.remove : _iconData = Icons.add;
});
},
);
}
}
}
祝你好运!