Flutter Custom Painter

时间:2018-08-16 14:56:05

标签: dart flutter flutter-layout flutter-animation

您好,我创建了一个扩展CustomPainter的小部件。问题是,当调用paint方法时,Size参数的width和height字段始终为0,0我不确定如何解决此问题。任何想法将不胜感激。这是小部件。谢谢!!

com.mongodb.MongoWaitQueueFullException: Too many threads are already waiting for a connection. Max number of threads (maxWaitQueueSize) of 500 has been exceeded.
    at com.mongodb.internal.connection.DefaultConnectionPool.createWaitQueueFullException(DefaultConnectionPool.java:280)
    at com.mongodb.internal.connection.DefaultConnectionPool.getAsync(DefaultConnectionPool.java:156)
    at com.mongodb.internal.connection.DefaultServer.getConnectionAsync(DefaultServer.java:98)
    at com.mongodb.binding.AsyncClusterBinding$AsyncClusterBindingConnectionSource.getConnection(AsyncClusterBinding.java:131)
    at com.mongodb.async.client.ClientSessionBinding$SessionBindingAsyncConnectionSource.getConnection(ClientSessionBinding.java:124)
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:509)
    at com.mongodb.operation.OperationHelper.access$100(OperationHelper.java:63)
    at com.mongodb.operation.OperationHelper$AsyncCallableWithConnectionAndSourceCallback.onResult(OperationHelper.java:529)
    at com.mongodb.operation.OperationHelper$AsyncCallableWithConnectionAndSourceCallback.onResult(OperationHelper.java:517)
    at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
    at com.mongodb.async.client.ClientSessionBinding$1.onResult(ClientSessionBinding.java:57)
    at com.mongodb.async.client.ClientSessionBinding$1.onResult(ClientSessionBinding.java:51)
    at com.mongodb.binding.AsyncClusterBinding$1.onResult(AsyncClusterBinding.java:105)
    at com.mongodb.binding.AsyncClusterBinding$1.onResult(AsyncClusterBinding.java:99)
    at com.mongodb.internal.connection.BaseCluster$ServerSelectionRequest.onResult(BaseCluster.java:433)
    at com.mongodb.internal.connection.BaseCluster.handleServerSelectionRequest(BaseCluster.java:297)
    at com.mongodb.internal.connection.BaseCluster.selectServerAsync(BaseCluster.java:157)
    at com.mongodb.internal.connection.MultiServerCluster.selectServerAsync(MultiServerCluster.java:54)
    at com.mongodb.binding.AsyncClusterBinding.getAsyncClusterBindingConnectionSource(AsyncClusterBinding.java:99)
    at com.mongodb.binding.AsyncClusterBinding.getWriteConnectionSource(AsyncClusterBinding.java:94)
    at com.mongodb.async.client.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:51)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:468)
    at com.mongodb.operation.MixedBulkWriteOperation.executeAsync(MixedBulkWriteOperation.java:211)
    at com.mongodb.async.client.OperationExecutorImpl$2.onResult(OperationExecutorImpl.java:112)
    at com.mongodb.async.client.OperationExecutorImpl$2.onResult(OperationExecutorImpl.java:104)
    at com.mongodb.async.client.ClientSessionHelper.createClientSession(ClientSessionHelper.java:66)
    at com.mongodb.async.client.ClientSessionHelper.withClientSession(ClientSessionHelper.java:51)
    at com.mongodb.async.client.OperationExecutorImpl.execute(OperationExecutorImpl.java:104)
    at com.mongodb.async.client.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1026)
    at com.mongodb.async.client.MongoCollectionImpl.executeUpdate(MongoCollectionImpl.java:701)
    at com.mongodb.async.client.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:659)
    at com.mongodb.reactivestreams.client.internal.MongoCollectionImpl$20.apply(MongoCollectionImpl.java:603)
    at com.mongodb.reactivestreams.client.internal.MongoCollectionImpl$20.apply(MongoCollectionImpl.java:600)
    at com.mongodb.async.client.SingleResultCallbackSubscription.requestInitialData(SingleResultCallbackSubscription.java:38)
    at com.mongodb.async.client.AbstractSubscription.tryRequestInitialData(AbstractSubscription.java:153)
    at com.mongodb.async.client.AbstractSubscription.request(AbstractSubscription.java:84)
at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1$1.request(ObservableToPublisher.java:50)

并以此方式使用:

class Box extends CustomPainter {
  double _top = 0.0;
  double _left = 0.0;
  double _width = 0.0;
  double _height = 0.0;
  String _text;

  Box(this._top, this._left, this._width, this._height, this._text);

  @override
  void paint(Canvas canvas, Size size) {
   canvas.drawRect(
      new Rect.fromLTWH(_left, _top, _width, _height),
      new Paint()
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2.0
        ..color = Colors.blue // new Color(0xFF0099FF),
  );
}

 @override
 bool shouldRepaint(Box oldDelegate) {
  return false;
 }
}

再次感谢您可能提出的想法!

2 个答案:

答案 0 :(得分:3)

多一点代码会有所帮助,但是我想我可以对您在这里所做的事情给出足够的解释。

我假设您的Positioned位于堆栈中,并且由于堆栈中的另一个元素(或由于放置在为其提供尺寸的小部件中),堆栈具有一定的尺寸。例如,如果堆栈位于SizedBox,Container(具有指定大小)或类似文件中,则它将具有一个大小。而如果它位于中心,则会根据其子项来调整自身大小。

如果堆栈按其子级调整大小,则会根据最大的未定位子级(即未包装在{{1 }}或包裹在Positioned中,但其位置未定义左侧,右侧,顶部,右侧,宽度或高度中的任何一个。

所以回到您的问题上-如果我们假设堆栈有一个大小,那么您的小部件将放在左上方。但是,按照书面规定,Positioned下的所有小部件都没有实际指定它们自己的大小-您尚未设置容器或CustomPaint的大小。

因此,您实际上需要指定CustomPaint的大小。如果知道特定的宽度/高度,则可以在Container或CustomPaint的尺寸中指定该宽度/高度。如果您不希望扩展到堆栈的大小,则可以简单地删除Positioned小部件,或者定义left / right和/或top / bottom。或者,您可以组合指定的高度或宽度+所需偏移量。最后一件事是,即使外部小部件的大小正确,CustomPaint仍可能决定将其大小调整为零。在这种情况下,您需要传递一个尺寸(我有把握地确定,如果您传递Positioned,它将扩大以填充其父元素)。

最后一件事是我不确定您对CustomPainter所做的事情,但似乎可能是错误的。如果您只是想绘制一个正方形,请使用传递给绘制器的尺寸而不是参数(我猜您正在尝试这样做是为了解决尺寸为零的问题)。

例如,如果您想简单地绘制一个填充整个绘画区域的矩形,请使用以下方法:

Size.infinite

但是,如果您传入东西,则需要确保未在自定义画家的范围之内绘制。来自CustomPaint文档:

  

画家应在从   原点并包含给定大小的区域。 (如果画家   在这些范围之外绘画,可能没有足够的内存   分配以光栅化绘画命令及其结果   行为是不确定的。)

答案 1 :(得分:0)

CustomPaint小部件的默认大小为Size.zero。要根据自己的喜好使用大小:

CustomPaint(
size: Size(100,100),
painter: MyPainter(),
),

要根据设备提供画布的宽度和高度,可以使用

double deviceWidth = MediaQuery.of(context).size.width;
double deviceHeight = MediaQuery.of(context).size.height;

在构建方法中初始化deviceWidth和deviceHeight并将其传递给CustomPaint小部件的size属性。

CustomPaint(
size: Size(deviceWidth,deviceHeight),
painter: MyPainter(),
),