【发布时间】:2021-08-23 02:30:54
【问题描述】:
我是 Flutter/dart 和响应式编程的新手,我一直在尝试解决这个问题。我在 DartPad 中构建了附加的测试代码,以确定我想在我的应用程序中做什么。我创建了一个有状态的小部件(DataRow),在它的状态对象(_dataRowState)中我有一个函数(setAndRefresher)。我正在尝试从不同的小部件(在 ElevatedButton 的 onPressed: 中)从小部件外部访问此功能:
datums[0].setAndRefresh!(datums[0].count + 1.0);
我已经建立了一个名为 Datum 的数据对象的全局列表,其中有一个名为 setAndRefresh 的回调成员。我在创建状态小部件时将列表中特定数据的索引传递给它,并使用它尝试将回调函数存储到该数据对象中:
基准[_datumIndex].setAndRefresh = setAndRefresher;
我确定我错过了什么,但不知道是什么。我正在尝试做的事情是否被阻止,如果是,为什么?我正在努力学习这门语言,就像我在努力解决这个问题一样。
import 'package:flutter/material.dart';
class Datum extends Object {
/// data storage object
double count = 0;
String word = 'Uninitialized';
Function? setAndRefresh;
void prt() {
print('word: $word – count: $count – callback: $setAndRefresh');
}
void incrementCount() {
print('incrementCount() -> $count');
count = count + 1;
print(' -> $count');
}
}
List<Datum> datums = [];
/// =============================================
void main() {
// Create three datum in a list
datums.add(Datum());
datums.add(Datum());
datums.add(Datum());
for (Datum dt in datums) {
dt.prt();
}
datums[0].word = 'All buttons total';
datums[1].word = 'Button 1 count';
datums[2].word = 'Button 2 count';
for (Datum dt in datums) {
dt.prt();
}
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Testing',
theme: ThemeData(
// primarySwatch: Colors.blue,
backgroundColor: Colors.green,
),
home: Scaffold(
appBar: AppBar(
brightness: Brightness.dark,
backgroundColor: Colors.green,
),
body: Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RichText(
text: const TextSpan(
text: 'Test Buttons',
),
),
const DataRow(datumIndex: 0),
const DataRow(datumIndex: 1),
const DataRow(datumIndex: 2),
],
),
),
);
}
}
/// =============================================
class DataRow extends StatefulWidget {
const DataRow({required this.datumIndex});
final int datumIndex;
@override
_DataRowState createState() => _DataRowState();
}
class _DataRowState extends State<DataRow> {
late int _datumIndex;
double count = 0;
@override
void initState() {
super.initState();
_datumIndex = widget.datumIndex;
print('Init setAndRefresh for $_datumIndex – callback: ${datums[_datumIndex].setAndRefresh}');
datums[_datumIndex].setAndRefresh = setAndRefresher;
print('Done init setAndRefresh for $_datumIndex – callback: ${datums[_datumIndex].setAndRefresh}');
}
void setAndRefresher({required double count}) {
print('Did set $count and refresh.');
setState(() {
datums[_datumIndex].count = count;
this.count = count;
});
}
@override
dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return lineItem(
name: '${datums[_datumIndex].word} is now: ${datums[_datumIndex].count} ',
color: Colors.orange,
);
}
Widget lineItem({required String name, required Color color}) {
return Container(
width: 500,
height: 50,
color: color,
child: Row(
children: <Widget>[
RichText(
text: TextSpan(text: name),
),
ElevatedButton(
onPressed: () {
print('Pressed Button $_datumIndex – callback: ${datums[_datumIndex].setAndRefresh}');
datums[_datumIndex].incrementCount();
setState(() {
count = datums[_datumIndex].count;
});
if (_datumIndex != 0 && datums[0].setAndRefresh != null) {
print('Now, increase All buttons total!()'); // This does print
datums[0].setAndRefresh!(datums[0].count + 1.0); // This is problem line?
print('Did it'); // this never prints
}
},
child: Text('Button ${widget.datumIndex}'),
),
],
),
);
}
}
此测试代码创建三个按钮。单击第一个按钮似乎可以工作,但是单击其他按钮中的任何一个都可以工作一次,然后该按钮似乎冻结了。以下是再次单击 Button1、Button0 和 Button0 所产生的控制台输出:
word: Uninitialized – count: 0 – callback: null
word: Uninitialized – count: 0 – callback: null
word: Uninitialized – count: 0 – callback: null
word: All buttons total – count: 0 – callback: null
word: Button 1 count – count: 0 – callback: null
word: Button 2 count – count: 0 – callback: null
Init setAndRefresh for 0 – callback: null
Done init setAndRefresh for 0 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
Init setAndRefresh for 1 – callback: null
Done init setAndRefresh for 1 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
Init setAndRefresh for 2 – callback: null
Done init setAndRefresh for 2 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
Script error.
Pressed Button 1 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
incrementCount() -> 0
-> 1
Now, increase All buttons total!()
Script error.
Pressed Button 0 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
incrementCount() -> 0
-> 1
Pressed Button 0 – callback: Closure: ({required double count}) => void from: function setAndRefresher() {
[native code]
}
incrementCount() -> 1
-> 2
【问题讨论】:
标签: flutter function dart callback instance