【问题标题】:How can I paint a Widget on a Canvas in Flutter?如何在 Flutter 的 Canvas 上绘制 Widget?
【发布时间】:2020-09-03 22:03:14
【问题描述】:

有没有办法在Canvas 的给定位置绘制Widget

更具体地说,我想在实际 FlutterMap 小部件前面的单独 Canvas 上绘制与 FlutterMap 相关的 Marker 的子小部件。这是创建CustomPainter 的尝试,但我不知道如何在画布上实际绘制小部件。使用RenderObject 需要PaintingContext,我不知道如何创建/检索:

class MarkerPainter extends CustomPainter {
  MapController mc;
  BuildContext context;
  List<Marker> markers;

  MarkerPainter(this.context, this.mc, this.markers);

  @override
  void paint(Canvas canvas, Size size) {
    if( markers != null && markers.isNotEmpty ){
      for(int i=0; i<markers.length; i++){
        Marker marker = markers[i];
        Offset o = myCalculateOffsetFromLatLng(marker.point, mc, context);

        // Won't work, this needs a PaintingContext...
        marker.builder(context).createElement().renderObject.paint(context, o); 
      }
    }
  }

  @override
  bool shouldRepaint(MarkerPainter oldDelegate) => oldDelegate.markers != markers;
}

【问题讨论】:

  • 用另一种方式解决了。作为其他希望在 FlutterMap 上进行自定义绘画的人的旁注:只需创建一个 FlutterMap 插件、图层选项和图层类。即 MyLayerPlugin 类扩展 MapPlugin,MyLayerOptions 类扩展 LayerOptions,MyLayer 类扩展 StatelessWidget。看看内置的 Layer 类(例如 MarkerLayer)是如何实现的,并在 MyLayer 类中实现类似的东西。然后在 FlutterMap 小部件上注册您的 MyLayerPlugin 并将您的图层添加为任何其他图层。
  • 如果您在 Answer 中分享您的解决方案会很棒

标签: flutter flutter-layout flutter-widget flutter-canvas fluttermap


【解决方案1】:

CustomPainter 无法做到这一点。

这个类只是对真实交易的简化:RenderObject,它可以访问与画家(和布局+更多)相关的所有内容。

你应该做的是,而不是CustomPainter,而是创建一个RenderBox(二维RenderObject

在您的情况下,您想要的是绘制一个小部件列表。在这种情况下,您需要创建:

总结一下,这样使用的小部件:

MyExample(
  children: [
    Text('foo'),
    Text('bar'),
  ],
),

应该这样写:

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

class MyExample extends MultiChildRenderObjectWidget {
  MyExample({
    Key? key,
    required List<Widget> children,
  }) : super(key: key, children: children);

  @override
  RenderMyExample createRenderObject(BuildContext context) {
    return RenderMyExample();
  }
}

class MyExampleParentData extends ContainerBoxParentData<RenderBox> {}

class RenderMyExample extends RenderBox
    with ContainerRenderObjectMixin<RenderBox, MyExampleParentData> {
  @override
  void setupParentData(RenderObject child) {
    if (child.parentData is! MyExampleParentData) {
      child.parentData = MyExampleParentData();
    }
  }

  @override
  void performLayout() {
    size = constraints.biggest;

    for (var child = firstChild; child != null; child = childAfter(child)) {
      child.layout(
        // limit children to a max height of 50
        constraints.copyWith(maxHeight: 50),
      );
    }
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    // Paints all children in order vertically, separated by 50px

    var verticalOffset = .0;
    for (var child = firstChild; child != null; child = childAfter(child)) {
      context.paintChild(child, offset + Offset(0, verticalOffset));

      verticalOffset += 50;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多