更新变量异步等待

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);