dart 如何在Flutter中为小部件分配future〈>?

s4n0splo  于 2023-01-28  发布在  Flutter
关注(0)|答案(6)|浏览(146)

假设我有一个SingleChildScrollView,它的内容是从一个文件中读取的:

singleChildScrollView(
        padding: EdgeInsets.all(8.0),
        child: nw Text(
          getTextFromFile(), //<---read from file
          style: TextStyle(
            fontWeight: FontWeight.bold,
            fontSize: 19.0,
          ),
        ));

  Future<String> getFileData(String path) async {
    return await rootBundle.loadString(path);
  }

  Future<String> getTextFromFile() async {
      return getFileData("test.txt");
  }

出现以下错误:

The argument type 'Future<String>' can't be assigned to the parameter
type 'String'.

如何解决这一问题?

7uzetpgm

7uzetpgm1#

使用FutureBuilder应该可以解决你的问题。我修改了你的代码,这样你就可以看到如何使用它。initialData不是必需的。

@override
  Widget build(BuildContext context) {
    return new FutureBuilder(
      future: getTextFromFile(),
      initialData: "Loading text..",
      builder: (BuildContext context, AsyncSnapshot<String> text) {
        return new SingleChildScrollView(
          padding: new EdgeInsets.all(8.0),
          child: new Text(
            text.data,
            style: new TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 19.0,
            ),
          ));
      });
  }

  Future<String> getFileData(String path) async {
    return await new Future(() => "test text");
  }

  Future<String> getTextFromFile() async {
    return getFileData("test.txt");
  }
}
z2acfund

z2acfund2#

StatefulWidget可用于此目的,声明成员变量String _textFromFile = "";并在将来解析时使用setState()方法更新其值。
我从构造函数调用了getTextFromFile()方法,但是您可以从任何地方调用它。
运行代码:

import 'package:flutter/material.dart';
import 'dart:async';

class StatefullWidgetDemo extends StatefulWidget {
  @override
  _StatefulWidgetDemoState createState() {
    return new _StatefulWidgetDemoState();
  }
}

class _StatefulWidgetDemoState extends State<StatefullWidgetDemo> {
  String _textFromFile = "";

  _StatefulWidgetDemoState() {
    getTextFromFile().then((val) => setState(() {
          _textFromFile = val;
        }));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Stateful Demo'),
      ),
      body: new SingleChildScrollView(
        padding: new EdgeInsets.all(8.0),
        child: new Text(
          _textFromFile,
          style: new TextStyle(
            fontWeight: FontWeight.bold,
            fontSize: 19.0,
          ),
        ),
      ),
    );
  }

  Future<String> getFileData(String path) async {
    return "your data from file";
  }

  Future<String> getTextFromFile() async {
    return await getFileData("test.txt");
  }
}
wxclj1h5

wxclj1h53#

此处简单回答=〉
调用函数的类:

@override
Widget build(BuildContext context) {
return new Scaffold(
 child: FutureBuilder(
  future: function(),
  builder: (BuildContext context, AsyncSnapshot<String> text) {
    return new Text(text.data);
  });
)}

和功能:

Future<String> function() async {
   return 'abc';
}
dced5bon

dced5bon4#

下面是一个类似的问题:
flutter / dart error: The argument type 'Future' can't be assigned to the parameter type 'File'
这里提出的解决方案非常优雅,并且工作正常。如果IDE要求使用Type而不是Future<Type>,请将await放在该参数前面

1tu0hz3e

1tu0hz3e5#

获取初始化数据的另一个解决方案是在initState()中调用getTextFromFile(),用新字符串设置状态,然后在小部件中使用该字符串:

String fileData = '';

Future<String> getFileData(String path) async {
    return await rootBundle.loadString(path);
  }

void getTextFromFile() async {
    try {
      String data = await getFileData("test.txt");
      setState(() {
        fileData = data;
      });
    } catch (ex) {
      print(ex);
    }
  }

  @override
  void initState() {
    super.initState();
    getTextFromFile();
  }

new singleChildScrollView(
        padding: new EdgeInsets.all(8.0),
        child: new Text(
          fileData,
          style: new TextStyle(
            fontWeight: FontWeight.bold,
            fontSize: 19.0,
          ),
        ));
t40tm48m

t40tm48m6#

我想再补充一个答案,因为我测试了其他的答案,我得到了一个错误。将异步部分(加上setState)从构造函数移到initState(),为我解决了这个问题。
好好享受

class TestAsyncInStateful extends StatefulWidget {
  const TestAsyncInStateful({super.key});

  @override
  State<TestAsyncInStateful> createState() => _TestAsyncInStatefulState();
}

class _TestAsyncInStatefulState extends State<TestAsyncInStateful> {
  @override
  void initState() {
    super.initState();

    getTextFromServer().then(
      (value) => setState(() {
        textFromServer = value;
      }),
    );
  }

  String? textFromServer;

  @override
  Widget build(BuildContext context) {
    return textFromServer == null? const SizedBox() :Text(textFromServer!);
  }
}

相关问题