更新变量异步等待
updating variable async await
我想在 phone 上做简单的“翻译”,单词来自 XML 名为“test.xml”的文件。
这是它的样子:
当我在 TextField
中输入正确的单词并单击按钮时,它会运行函数 getXmlFile()
并将其值存储在 _translatedText2
中:
ButtonClass(
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("value of var where should be translation: $_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
)
此函数从 test.xml
获取值并将其转换为已翻译单词列表。
我正在粘贴 getXmlFile()
:
Future<List<String>> getXmlFile(BuildContext context, _typedText) async {
String xmlString =
await DefaultAssetBundle.of(context).loadString("assets/test.xml");
var raw = xml.XmlDocument.parse(xmlString);
var elements = raw.findAllElements(_typedText);
return elements.map((node) {
return (node.text);
}).toList();
}
所以,问题出在哪里???
_translatedText2
有翻译文本的价值,很好,但他只有在第二次点击后才获得它,然后我在屏幕上看到我的翻译。应该马上就到了。
我的有益观察
第一次点击后 _translatedText2
是空的。我知道它是因为我在 getXmlFile()
之后打印了它的值(这个 print()
在代码中),它打印出空的字符串列表。
正如我所说,只有在第二次点击按钮后,它才会打印出正确的值。那是个问题。
ButtonClass
(为了更具可读性而缩短):
class ButtonClass extends StatefulWidget {
ButtonClass({Key? key, required this.whenClick}) : super(key: key);
VoidCallback whenClick;
@override
State<ButtonClass> createState() => _ButtonClassState();
}
class _ButtonClassState extends State<ButtonClass> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: widget.whenClick,
child: const Icon(
Icons.translate,
));
}
}
最后是 MyHomePage
(为了更易读而缩短):
void main() {
runApp(const MyApp());
WidgetsFlutterBinding.ensureInitialized();
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage("text"),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage(String text, {Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
final _searchValue = TextEditingController();
String _typedText = "finding txt";
String _translatedText1 = "translation";
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
getXmlFile(context, _typedText);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
Text(
"Search Word",
style: GoogleFonts.overpass(
fontSize: 40, color: Colors.white, fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 104.0),
child: TextField(
controller: _searchValue,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.search),
hintText: "Enter Word",
),
),
),
Center(child: ButtonClass(
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("wartosc po funkcji:$_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
)),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Text("finding text::"),
Text(_typedText,
textAlign: TextAlign.center,
style: GoogleFonts.overpass(
color: Colors.green,
))
]),
Wrap(children: [
Text("translation:"),
Text(_translatedText1,
textAlign: TextAlign.center,
style: GoogleFonts.overpass(
color: Colors.red,
))
])
]));
}
}
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("value of var where should be translation: $_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
在此代码块中,您搜索 _typedText
但仅 set 如果 after 搜索完成。所以你的结果基本上总是落后一步。
该行应该是:
final _translatedText2 = await getXmlFile(context, _searchValue.text);
我想在 phone 上做简单的“翻译”,单词来自 XML 名为“test.xml”的文件。 这是它的样子:
当我在 TextField
中输入正确的单词并单击按钮时,它会运行函数 getXmlFile()
并将其值存储在 _translatedText2
中:
ButtonClass(
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("value of var where should be translation: $_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
)
此函数从 test.xml
获取值并将其转换为已翻译单词列表。
我正在粘贴 getXmlFile()
:
Future<List<String>> getXmlFile(BuildContext context, _typedText) async {
String xmlString =
await DefaultAssetBundle.of(context).loadString("assets/test.xml");
var raw = xml.XmlDocument.parse(xmlString);
var elements = raw.findAllElements(_typedText);
return elements.map((node) {
return (node.text);
}).toList();
}
所以,问题出在哪里???
_translatedText2
有翻译文本的价值,很好,但他只有在第二次点击后才获得它,然后我在屏幕上看到我的翻译。应该马上就到了。
我的有益观察
第一次点击后 _translatedText2
是空的。我知道它是因为我在 getXmlFile()
之后打印了它的值(这个 print()
在代码中),它打印出空的字符串列表。
正如我所说,只有在第二次点击按钮后,它才会打印出正确的值。那是个问题。
ButtonClass
(为了更具可读性而缩短):
class ButtonClass extends StatefulWidget {
ButtonClass({Key? key, required this.whenClick}) : super(key: key);
VoidCallback whenClick;
@override
State<ButtonClass> createState() => _ButtonClassState();
}
class _ButtonClassState extends State<ButtonClass> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: widget.whenClick,
child: const Icon(
Icons.translate,
));
}
}
最后是 MyHomePage
(为了更易读而缩短):
void main() {
runApp(const MyApp());
WidgetsFlutterBinding.ensureInitialized();
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage("text"),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage(String text, {Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
final _searchValue = TextEditingController();
String _typedText = "finding txt";
String _translatedText1 = "translation";
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
getXmlFile(context, _typedText);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
Text(
"Search Word",
style: GoogleFonts.overpass(
fontSize: 40, color: Colors.white, fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 104.0),
child: TextField(
controller: _searchValue,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.search),
hintText: "Enter Word",
),
),
),
Center(child: ButtonClass(
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("wartosc po funkcji:$_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
)),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Text("finding text::"),
Text(_typedText,
textAlign: TextAlign.center,
style: GoogleFonts.overpass(
color: Colors.green,
))
]),
Wrap(children: [
Text("translation:"),
Text(_translatedText1,
textAlign: TextAlign.center,
style: GoogleFonts.overpass(
color: Colors.red,
))
])
]));
}
}
whenClick: () async {
final _translatedText2 = await getXmlFile(context, _typedText);
print("value of var where should be translation: $_translatedText2");
setState(() {
_typedText = _searchValue.text;
_translatedText1 = _translatedText2.toString();
});
},
在此代码块中,您搜索 _typedText
但仅 set 如果 after 搜索完成。所以你的结果基本上总是落后一步。
该行应该是:
final _translatedText2 = await getXmlFile(context, _searchValue.text);