ValueNotifier:在页面构建完成之前更新小部件的文本会引发异常



我试图计算一个百分比,并将其设置为文本小部件,同时建立一个页面。在我的应用程序中,我有一个设置页面,通过点击ListTile将用户带到一个新页面。在新的页面(percentage_settings_page.dart)中,我从我的SQLITE数据库中读取数据,该数据库包含一些使用FutureBuilder<List<User>>ListView.builder()的用户。

在构建包含姓名和每个用户百分比的列表视图时,我需要计算剩余的百分比,这是通过从100中减去用户百分比的总和给出的,并将其设置在圆形指示器中。我正试图使用ValueNotifier来实现这一点。这是页面的样子:

如何:显示100

该怎么做

percentage_settings_page.dart:

class _PercentageSettingsPageState extends State<PercentageSettingsPage> {
/* other variables */
final ValueNotifier<double> _myPercentage = ValueNotifier<double>(100);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Divide percentage'),
leading: BackButton(
onPressed: () async => Navigator.pop(context),
),
),
body: SafeArea(
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 20),
child: Align(
alignment: Alignment.topCenter,
child: CircularPercentIndicator(
radius: 120.0,
lineWidth: 10.0,
animation: true,
center: ValueListenableBuilder(
valueListenable: _myPercentage,
builder:
(BuildContext context, double value, Widget? child) {
return Text(
'$value', // <- this text should be updated
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
);
}),
footer: const Text(
'Remaining percentage',
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 17.0),
),
circularStrokeCap: CircularStrokeCap.round,
progressColor: Colors.orange,
),
),
),
SafeArea(
child: _buildUsersFromDB(),
),
],
),
),
);
}
Widget _buildUsersFromDB() {
return FutureBuilder<List<User>>(
future: _userDAO.readData(),
builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data!.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int i) {
return Card(
elevation: 2,
margin: const EdgeInsets.all(5),
child: _buildRow(snapshot.data![i]),
);
},
)
: const Center(
child: CircularProgressIndicator(),
);
});
}
Widget _buildRow(User user) {
_myPercentage.value -= user.percentage; // <- This line gives me problems
return ListTile(
title: Text(
user.name,
style: _biggerFont,
),
trailing: Text('${user.percentage} %'),
onTap: () => _showDoubleDialog(user).then((value) {
/* some code */
}),
);
}
}

但是当我运行应用程序时,我得到以下错误:

════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for ValueNotifier<double>:
setState() or markNeedsBuild() called during build.
This ValueListenableBuilder<double> widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: ValueListenableBuilder<double>
state: _ValueListenableBuilderState<double>#5709e
The widget which was currently being built when the offending call was made was: SliverList
delegate: SliverChildBuilderDelegate#e6e08(estimated child count: 3)
renderObject: RenderSliverList#aacf6 relayoutBoundary=up15 NEEDS-LAYOUT NEEDS-PAINT
When the exception was thrown, this was the stack
#0      Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4217
#1      Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4232
#2      State.setState
package:flutter/…/widgets/framework.dart:1108
#3      _ValueListenableBuilderState._valueChanged
package:flutter/…/widgets/value_listenable_builder.dart:182
#4      ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:243
...
The ValueNotifier<double> sending notification was: ValueNotifier<double>#5ee2d(89.2)

是否有人知道我如何才能实现这一目标,或者当试图在建筑期间/之后设置小部件时,最佳实践是什么?

编辑:我需要ValueNotifier,因为每当单个用户的百分比更新时,我需要更新剩余的百分比(这是通过点击用户并选择新的百分比来完成的)

我只是将_userDAO.readData()的调用向上移动,并在此基础上添加标题文本和列表项。这将消除对_myPercentageValueNotifier的需求。

相关内容

最新更新