Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Canvas 颤振-画布绘制Z顺序_Canvas_Dart_Flutter - Fatal编程技术网

Canvas 颤振-画布绘制Z顺序

Canvas 颤振-画布绘制Z顺序,canvas,dart,flutter,Canvas,Dart,Flutter,使用Flatter的CustomPainter在画布中绘制各种图像s,然后在屏幕上渲染。我期望任何绘制的重叠图像的深度顺序与在画布上绘制的相同(例如,Canvas.drawImage(图像1,…);Canvas.drawImage(图像2,…);Canvas.drawImage(图像3,…)将在屏幕上呈现三个图像,其中image1分别出现在image2和image3下方。然而,我发现在某些情况下,渲染图像的顺序并没有完全保留 请参见下面的示例代码: import 'dart:async'; im

使用Flatter的
CustomPainter
画布中绘制各种
图像
s,然后在屏幕上渲染。我期望任何绘制的重叠图像的深度顺序与在画布上绘制的相同(例如,
Canvas.drawImage(图像1,…);Canvas.drawImage(图像2,…);Canvas.drawImage(图像3,…)
将在屏幕上呈现三个图像,其中
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;
}
导入'dart:async';
将“dart:ui”导入为ui;
进口“包装:颤振/材料.省道”;
导入“包:flifter/services.dart”;
导入“包:flatter/services.dart”显示根包;
void main()=>runApp(新示例app());
类ExampleApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“基本示例”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:ExampleScreen(),
);
}
}
类ExampleScreen扩展StatefulWidget{
最终偏移量initPos=偏移量(0.0,0.0);
@凌驾
_示例ScreenState createState()=>_示例ScreenState();
}
类\u示例ScreenState扩展状态{
ui.Image\u image1;
ui.Image\u image2;
ui.Image\u image3;
预习;
@凌驾
void initState(){
_预处理=假;
super.initState();
//_draggedToOffset=widget.initPos;
}
_示例ScreenState(){
_准备();
}
_准备(){
loadImage('assets/wfw_1.png')。然后((image1){
_image1=image1;
}).完成时(){
loadImage('assets/wnfw_2.png')。然后((image2){
_image2=image2;
}).完成时(){
loadImage('assets/wfw_1.png')。然后((image3){
_image3=image3;
}).完成时(){
_prepDone=true;
_句柄();
});
});
});
}
_句柄(){
setState((){});
}
@凌驾
小部件构建(构建上下文){
退回新货柜(
约束:BoxConstraints.expand(),
颜色:颜色。灰色,
子级:新堆栈(子级:[
_预处理?容器(子:buildPainter()):容器()
]));
}
建筑油漆工(){
返回容器(
孩子:定制油漆(
画家:例如画家(_image1,_image2,_image3),
));
}
}
类ExamplePainter扩展了CustomPainter{
ui.Image\u image1;
ui.Image\u image2;
ui.Image\u image3;
油漆_油漆=油漆();
例如画家(这个。_图像1,这个。_图像2,这个。_图像3);
@凌驾
空心油漆(帆布,尺寸){
画布.drawImage(_image1,偏移量(100.0,35.0),_paint);
画布.drawImage(_image2,偏移量(70.0,50.0),_paint);
画布.drawImage(_image3,偏移量(40.0,65.0),_paint);
}
@凌驾
bool应重新绘制(例如Painter oldDelegate){
返回true;
}
}
未来加载映像(字符串assetPath)异步{
ImageStream=新的AssetImage(assetPath,bundle:rootBundle)
.resolve(ImageConfiguration.empty);
Completer Completer=新的Completer();
无效侦听器(ImageInfo帧,bool synchronousCall){
最终ui.Image=frame.Image;
完成(图像);
stream.RemovelListener(监听器);
}
addListener(监听器);
返回completer.future;
}
其中:
image1
image3
是:。
image2
是:

Renderer输出在我的笔记本电脑的Android Emulator设备上如下所示:

可以看出,
image2
是在最后绘制的图像(
image3
)之上渲染的,当时我希望它在
image2
(即介于
image1
image3
之间)之下渲染

我能够解决该问题的唯一方法是: 在
drawImage(..)
调用之间添加一个虚拟
drawRect(..)
调用,或者通过将
image2
Offset.dy
设置为
Offset.dy+0.001

我对Dart和Flatter基本上是新手,所以我不确定是a)我的代码错了,b)我对Flatter渲染引擎的理解错了,还是c)Dart:ui中某个地方有个bug?

我想是c)因为在更新到
Flatter版本0.10.2
后,顺序现在保持不变