flutter - State.initState() 必须是没有 `async` 关键字的 void 方法

标签 flutter dart

![State.initState() must be a void method without an async keyword. how can i solve this probelms] 1

how to solve this problem

@override
  Future<void> initState() async {
    // TODO: implement initState
    super.initState();
    _current_location();
    BitmapDescriptor.fromAssetImage(
        ImageConfiguration(devicePixelRatio: 2.5),
        'assets/fff.png').then((onValue) {
      pinLocationIcon = onValue;
    });
    //createCustomMarker(context);

   // final Marker marker = Marker(icon: BitmapDescriptor.fromBytes(markerIcon));
    DatabaseReference ref = FirebaseDatabase.instance.reference();
    ref.child('users').once().then((DataSnapshot snapshot) {
      Map<dynamic, dynamic> values = snapshot.value;
      print(values.toString());
      values.forEach((k, v) {
        allMarkers.add(Marker(
          markerId: MarkerId(k),
          draggable: false,
          icon: pinLocationIcon,
          position: LatLng(v["latitude"], v["longitude"]),
          infoWindow: InfoWindow(title: v["name"]),
          onTap: () {
            _onMarkerTapped(v["name"]);
          },
        ),);
      });
    });
  }

最佳答案

initState必须是不带参数并返回 void 的方法.这是因为它覆盖了父类(super class)中的同名方法(StatelessWidgetState<StatefulWidgetType>。因此,此限制是一个固定且具有约束力的契约(Contract);您无法更改它。
当然,这也意味着initState不能标记为 async .这是因为任何标记为 async 的方法将隐式返回 Future ,但如果该方法返回任何内容,则它的返回类型不能为 void这违反了覆盖契约(Contract)。
如果您需要调用async initState 内部的方法, 你可以通过不 await 来做到这一点把它:

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

Future<void> doSomeAsyncStuff() async {
  ...
}
但是,如果您需要来自 async 的数据方法,您不能简单地等待 Future在构建小部件之前返回。 Flutter 不允许这样做,因为不知道 Future 需要多长时间。返回,并在此之前停止构建小部件可能会阻止您的整个应用程序。
相反,您需要让您的小部件正常构建,然后有办法通知您的小部件在 Future 更新时进行更新。已经回来了。使用 FutureBuilder 最容易做到这一点。 :
@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: doSomeAsyncStuff(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        // Future hasn't finished yet, return a placeholder
        return Text('Loading');
      }
      return Text('Loading Complete: ${snapshot.data}');
    }
  );
}
(请注意,在构建过程中,我不是从 async 调用 initState 方法,而是从 FutureBuilder 调用它。)

编辑:正如所指出的,这种方法仅适用于 OP 的情况,即等待的 future 总是最终返回一个值。情况并非总是如此——有时 future 根本不会返回值,而只是一个长期运行的过程。有时 future 可能会返回 null 而不是具体数据。有时 future 可能会导致错误而不是成功完成。在任何这些情况下,snapshot.data future 完成后将为空,在这种情况下 snapshot.hasData永远是假的。
在这些情况下,而不是依赖于 snapshot.hasData要等待数据出现,您可以使用 snapshot.connectionState监控 future 本身的状态:
@override
Widget build(BuildContext context) {
 return FutureBuilder(
   future: doSomeAsyncStuff(),
   builder: (context, snapshot) {
     if (snapshot.connectionState != ConnectionState.done) {
       // Future hasn't finished yet, return a placeholder
       return Text('Loading');
     }
     return Text('Loading Complete');
   }
 );
}

关于flutter - State.initState() 必须是没有 `async` 关键字的 void 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61764400/

相关文章:

flutter - 如何从集成测试中选择时间选择器

flutter - 如何在Flutter中使用设备日历获取事件

dart - Sqljocky抛出SocketException

firebase - 如何打印有意义的 firebase-dart 异常

flutter - 为什么我的 RaisingButton 在 Flutter 中不起作用?

inheritance - 覆盖上层类(Class)的变量

dart - 出现ScriptCompactor错误,无法内联导入文件

dart - 为什么String.endsWith取String时String.startsWith取Pattern作为输入

flutter - 如何解决 '_positions.isNotEmpty' : ScrollController not attached to any scroll views?

android - 如何使用工具 :overrideLibrary ="io.flutter.plugins.camera"