Flutter Necestelesswidget和提供商未更新或调用不必要的构建
我正在尝试将提供商
与无状态
窗口小部件页面更新倒计时UI。
在控制台中获得两个打印消息:
当我运行
flutter: build()
flutter: _buildCountDown()
以下所有操作时,我在秒表的每个1秒刻度上都会
如果我:
- 使页面a
statefulwidget
- 用
consumer< CountdownProvider>
语法替换变量访问
return Consumer<CountdownProvider>(
builder: (_, countdownProvider, __) {
return Text(countdownProvider.remaining.toString()),
});
但是, UI正确更新,我没有获得build()
打印输出,只有_buildCountdown()
,这就是我想要的。
q)我做错了什么,这意味着我无法将其作为预期更新的无状态小部件?
- main。dart我有这样的提供商:
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => CountdownProvider(),
),
],
)
- 我写了一个简单的倒计时提供商-g code-
CountDownProvider
:
class CountdownProvider extends ChangeNotifier {
int remaining = 0;
final Stopwatch _stopwatch = Stopwatch();
late Timer _timer;
void start(int val) {
remaining = val;
_timer = Timer.periodic(const Duration(seconds: 1), _onTick);
_stopwatch.start();
}
void _onTick(Timer timer) {
remaining--;
if (remaining < 0) {
return;
}
notifyListeners();
}
void stop(bool skipNotify) {
_timer.cancel();
_stopwatch.stop();
if (skipNotify) {
_stopwatch.reset();
remaining = 0;
return;
}
notifyListeners();
}
}
- 页面显示它:
pagecountdown
:
class PageCountdown extends StatelessWidget {
const PageCountdown({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// 10 seconds default countdown
Provider.of<CountdownProvider>(context, listen: false).start(10);
print("build()");
return Scaffold(
body: _buildContent(context),
);
}
Widget _buildContent(BuildContext context) {
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildCountDown(context),
],
),
);
}
Widget _buildCountDown(BuildContext context) {
int remaining = Provider.of<CountdownProvider>(context).remaining;
print("_buildCountDown()");
return Text(
remaining.toString(),
);
}
}
I'm trying to use Provider
with a Stateless
widget page to update a countdown UI.
When I run all the below, I get both print messages in the console on each 1 second tick of the stopwatch:
e.g.
flutter: build()
flutter: _buildCountDown()
Also, the remaining
value doesn't actually update in the UI.
But if I:
- make the page a
StatefulWidget
- replace the variable access with
Consumer<CountdownProvider>
syntax e.g.
return Consumer<CountdownProvider>(
builder: (_, countdownProvider, __) {
return Text(countdownProvider.remaining.toString()),
});
...everything works as expected: the UI updates properly and I don't get the build()
printout, just the _buildCountDown()
, which is what I wanted.
Q) What am I doing wrong that means I can't make this a Stateless widget that updates as expected?
- main.dart I have the Provider like so:
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => CountdownProvider(),
),
],
)
- I have written a simple countdown provider -
CountdownProvider
:
class CountdownProvider extends ChangeNotifier {
int remaining = 0;
final Stopwatch _stopwatch = Stopwatch();
late Timer _timer;
void start(int val) {
remaining = val;
_timer = Timer.periodic(const Duration(seconds: 1), _onTick);
_stopwatch.start();
}
void _onTick(Timer timer) {
remaining--;
if (remaining < 0) {
return;
}
notifyListeners();
}
void stop(bool skipNotify) {
_timer.cancel();
_stopwatch.stop();
if (skipNotify) {
_stopwatch.reset();
remaining = 0;
return;
}
notifyListeners();
}
}
- Page to display it:
PageCountdown
:
class PageCountdown extends StatelessWidget {
const PageCountdown({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// 10 seconds default countdown
Provider.of<CountdownProvider>(context, listen: false).start(10);
print("build()");
return Scaffold(
body: _buildContent(context),
);
}
Widget _buildContent(BuildContext context) {
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildCountDown(context),
],
),
);
}
Widget _buildCountDown(BuildContext context) {
int remaining = Provider.of<CountdownProvider>(context).remaining;
print("_buildCountDown()");
return Text(
remaining.toString(),
);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PageCountdown
是单个小部件,在计数器滴答时会重建。start(10)
在构建的开头
将重置剩余每个重建。这样的事情将起作用:PageCountdown
is the single widget, which is rebuilt when the counter ticks.start(10)
in the beginning ofbuild
will resetremaining
to 10 every rebuild. Something like this will work: