在此 Flutter/Dart 代码中,无法将“Future<Image>”分配给“Image”类型的变量?

问题描述

我正在尝试创建一个函数来在 Flutter (Dart) 中加载图像,但不确定如何使此代码正常工作。我得到:

“Future”类型的值不能分配给“Image”类型的变量。 尝试更改变量的类型,或将右侧类型转换为“图像”。

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:Flutter/material.dart';
import 'package:Flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ui.Image _backgroundImage;

  Future<ui.Image> loadImage(imageString) async {
    ByteData bd = await rootBundle.load(imageString);
    // ByteData bd = await rootBundle.load("graphics/bar-1920×1080.jpg");
    final Uint8List bytes = Uint8List.view(bd.buffer);
    final ui.Codec codec = await ui.instantiateImageCodec(bytes);
    final ui.Image image = (await codec.getNextFrame()).image;
    return image;
    // setState(() => imageStateVarible = image);
  }  

  @override
  Widget build(BuildContext context) {
    setState( () => {
      _backgroundImage = loadImage('imageNameString');  // <<== ISSUE: A value of type 'Future<Image>' can't be assigned to a variable of type 'Image'
    });

    return Scaffold(
      body: Center(
        child: Text('testing'),),);
  }
}

解决方法

试试这个。您的问题是:

  1. 不应在 build.gradle 中调用诸如“下载图像”之类的东西。那应该是一个纯函数。
  2. 您的 loadImage 是异步的。因此我在 _asyncInit 中调用它。此外,您可能只想加载图像一次(而不是每次构建),所以我放入了 initState。
import 'dart:typed_data';
import 'dart:ui' as ui;

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ui.Image _backgroundImage;

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

  Future<void> _asyncInit() async {
    final image = await loadImage('imageNameString');
    setState(() {
      _backgroundImage = image;
    });
  }

  Future<ui.Image> loadImage(imageString) async {
    ByteData bd = await rootBundle.load(imageString);
    // ByteData bd = await rootBundle.load("graphics/bar-1920×1080.jpg");
    final Uint8List bytes = Uint8List.view(bd.buffer);
    final ui.Codec codec = await ui.instantiateImageCodec(bytes);
    final ui.Image image = (await codec.getNextFrame()).image;
    return image;
    // setState(() => imageStateVarible = image);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _backgroundImage != null ? YourWidget(_backgroundImage) : Text('you are loading that image'),),);
  }
}

编辑

如果你想要一组图像:

import 'dart:typed_data';
import 'dart:ui' as ui;

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<ui.Image> _backgroundImages;

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

  Future<void> _asyncInit() async {
    final imageNames = ['firstimage','secondimage','thirdimage'];
    // NOTE by doing this,your images are loaded **simutanously** instead of **waiting for one to finish before starting the next**
    final futures = [for (final name in imageNames) loadImage(name)];
    final images = await Future.wait(futures);
    setState(() {
      _backgroundImages = images;
    });
  }

  Future<ui.Image> loadImage(imageString) async {
    ByteData bd = await rootBundle.load(imageString);
    // ByteData bd = await rootBundle.load("graphics/bar-1920×1080.jpg");
    final Uint8List bytes = Uint8List.view(bd.buffer);
    final ui.Codec codec = await ui.instantiateImageCodec(bytes);
    final ui.Image image = (await codec.getNextFrame()).image;
    return image;
    // setState(() => imageStateVarible = image);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _backgroundImages != null ? YourWidget(_backgroundImages) : Text('you are loading that image'),);
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...