Flutter-画布绘制Z顺序

时间:2018-11-07 20:42:29

标签: canvas dart flutter

使用Flutter的CustomPainterImage中绘制各种Canvas,然后在屏幕上进行渲染。我的期望是,任何绘制的重叠图像在画布上绘制时的深度顺序(例如,canvas.drawImage(image1,..); canvas.drawImage(image2,..); canvas.drawImage(image3,..);会在屏幕上image1出现在image2下方的情况下渲染三个图像,并且image3)。但是我发现,在某些情况下,渲染图像的顺序并没有完全保留。

请参见下面的示例代码:

import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/services.dart' show rootBundle;

void main() => runApp(new ExampleApp());

class ExampleApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Ground Example',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ExampleScreen(),
    );
  }
}

class ExampleScreen extends StatefulWidget {
  final Offset initPos = Offset(0.0, 0.0);

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

class _ExampleScreenState extends State<ExampleScreen> {
  ui.Image _image1;
  ui.Image _image2;
  ui.Image _image3;
  bool _prepDone;

  @override
  void initState() {
    _prepDone = false;
    super.initState();
    //_draggedToOffset = widget.initPos;
  }

  _ExampleScreenState() {
    _prepare();
  }

  _prepare() {
    loadImage('assets/wfw_1.png').then((image1) {
      _image1 = image1;
    }).whenComplete(() {
      loadImage('assets/wnfw_2.png').then((image2) {
        _image2 = image2;
      }).whenComplete(() {
        loadImage('assets/wfw_1.png').then((image3) {
          _image3 = image3;
        }).whenComplete(() {
          _prepDone = true;
          _handle();
        });
      });
    });
  }

  _handle() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
        constraints: BoxConstraints.expand(),
        color: Colors.grey,
        child: new Stack(children: <Widget>[
          _prepDone ? Container(child: buildPainter()) : Container()
        ]));
  }

  buildPainter() {
    return Container(
        child: CustomPaint(
          painter: ExamplePainter(_image1, _image2, _image3),
        ));
  }
}

class ExamplePainter extends CustomPainter {
  ui.Image _image1;
  ui.Image _image2;
  ui.Image _image3;
  Paint _paint = Paint();

  ExamplePainter(this._image1, this._image2, this._image3);

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawImage(_image1, Offset(100.0, 35.0), _paint);
    canvas.drawImage(_image2, Offset(70.0, 50.0), _paint);
    canvas.drawImage(_image3, Offset(40.0, 65.0), _paint);
  }

  @override
  bool shouldRepaint(ExamplePainter oldDelegate) {
    return true;
  }
}

Future<ui.Image> loadImage(String assetPath) async {
  ImageStream stream = new AssetImage(assetPath, bundle: rootBundle)
      .resolve(ImageConfiguration.empty);
  Completer<ui.Image> completer = new Completer<ui.Image>();
  void listener(ImageInfo frame, bool synchronousCall) {
    final ui.Image image = frame.image;
    completer.complete(image);
    stream.removeListener(listener);
  }

  stream.addListener(listener);
  return completer.future;
}

其中:  image1image3是:wfw_1.png。  image2是:wnfw_2.png

在笔记本电脑的Android模拟器设备上,renderer输出如下:

rendered output

可以看出,当我希望将image2绘制在image3以下(即介于{{1 }}和image2

解决该问题的唯一方法是: 在image1呼叫之间添加虚拟image3呼叫,或者通过将drawRect(..)的{​​{1}}设置为drawImage(..)来添加呼叫。

我一般是Dart和Flutter的新手,所以我不确定是否是a)我的代码错误,b)我对Flutter渲染引擎的理解是错误的,或者c)dart:ui中的错误?

1 个答案:

答案 0 :(得分:0)

我认为是c),因为在更新为flutter version 0.10.2之后,订单得以保留。