嵌套行/列中的颤振展开图

时间:2019-08-26 09:58:28

标签: flutter flutter-layout

我正在尝试从charts_flutter package获取一个图表,以进行扩展以填充可用空间,前提是该图表位于“行”或“列”内。我已经花了几个小时试图做到这一点,但我一定错过了一些东西!从视觉上看,这就是我要实现的目标:

enter image description here

这是一个最小的工作示例。我一定已经尝试了一百种扩展,柔性,主轴尺寸,横轴对齐等组合,但是我似乎找不到正确的组合。当前,底部以object was given an infinite size during layout溢出无限像素。有this open issue,我不知道是否相关,也没有答案。我只需要runApp内的一些代码的帮助:

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

void main() => runApp(

  // HOW DO I LAY THIS OUT?
  Column(
    children: <Widget>[
      Container(height: 200, color: Colors.orange),
      Row(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          Container(width: 200,color: Colors.orange),
          Expanded(child: SimpleTimeSeriesChart.withSampleData())
        ],
      )
    ],
  )
);

class SimpleTimeSeriesChart extends StatelessWidget {
  final List<charts.Series> seriesList;
  final bool animate;

  SimpleTimeSeriesChart(this.seriesList, {this.animate});

  factory SimpleTimeSeriesChart.withSampleData() {
    return new SimpleTimeSeriesChart(
      _createSampleData(),
      animate: false,
    );
  }

  @override
  Widget build(BuildContext context) {
    return new charts.TimeSeriesChart(
      seriesList,
      animate: animate,
      dateTimeFactory: const charts.LocalDateTimeFactory(),
    );
  }

  /// Create one series with sample hard coded data.
  static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
    final data = [
      new TimeSeriesSales(new DateTime(2017, 9, 19), 5),
      new TimeSeriesSales(new DateTime(2017, 9, 26), 25),
      new TimeSeriesSales(new DateTime(2017, 10, 3), 100),
      new TimeSeriesSales(new DateTime(2017, 10, 10), 75),
    ];

    return [
      new charts.Series<TimeSeriesSales, DateTime>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        domainFn: (TimeSeriesSales sales, _) => sales.time,
        measureFn: (TimeSeriesSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

class TimeSeriesSales {
  final DateTime time;
  final int sales;

  TimeSeriesSales(this.time, this.sales);
}

2 个答案:

答案 0 :(得分:2)

**在第8步中查看原因-向下滚动?**

问题

  

我正试图从Charts_flutter包中获取一张图表,以进行扩展以填充可用空间

错误证据

  

对象在布局过程中被赋予了无限大小

解决方案

用扩展行包裹行

Column(children: <Widget>[Expanded(child: Row())])

屏幕截图

enter image description here

注意:

  • ?,感谢您提供最少的代码

完整的工作代码

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

void main() => runApp(

        // HOW DO I LAY THIS OUT?
        Column(
      children: <Widget>[
        Container(height: 200, color: Colors.orange),
        Expanded(
          child: Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              Container(width: 200, color: Colors.green),
              Expanded(child: SimpleTimeSeriesChart.withSampleData()),
            ],
          ),
        )
      ],
    ));

class SimpleTimeSeriesChart extends StatelessWidget {
  final List<charts.Series> seriesList;
  final bool animate;

  SimpleTimeSeriesChart(this.seriesList, {this.animate});

  factory SimpleTimeSeriesChart.withSampleData() {
    return new SimpleTimeSeriesChart(
      _createSampleData(),
      animate: false,
    );
  }

  @override
  Widget build(BuildContext context) {
    return new charts.TimeSeriesChart(
      seriesList,
      animate: animate,
      dateTimeFactory: const charts.LocalDateTimeFactory(),
    );
  }

  /// Create one series with sample hard coded data.
  static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
    final data = [
      new TimeSeriesSales(new DateTime(2017, 9, 19), 5),
      new TimeSeriesSales(new DateTime(2017, 9, 26), 25),
      new TimeSeriesSales(new DateTime(2017, 10, 3), 100),
      new TimeSeriesSales(new DateTime(2017, 10, 10), 75),
    ];

    return [
      new charts.Series<TimeSeriesSales, DateTime>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        domainFn: (TimeSeriesSales sales, _) => sales.time,
        measureFn: (TimeSeriesSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

class TimeSeriesSales {
  final DateTime time;
  final int sales;

  TimeSeriesSales(this.time, this.sales);
}

其他:如何读取错误(末尾附有完整错误转储)

第1步:找到起点

I/flutter ( 4228): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════

第2步:找到终点

I/flutter ( 4228): ════════════════════════════════════════════════════════════════════════════════════════════════════

步骤3:读取错误

用眼睛扫描错误,您会看到一些短语


I/flutter ( 4228):     constraints: BoxConstraints(w=320.0, h=480.0)

I/flutter ( 4228): The following assertion was thrown during performLayout():

I/flutter ( 4228): Summary 1: RenderCustomMultiChildLayoutBox object was given an infinite size during layout.

第4步:确定什么类型

这是 框约束 错误

第5步:如何知道哪个小部件引发了错误

走到尽头,它将为您提供来源:

I/flutter ( 4228):   creator: CustomMultiChildLayout ← TimeSeriesChart ← SimpleTimeSeriesChart ← Expanded ← Row ← Column
I/flutter ( 4228):     ← [root]
  • 因此它位于TimeSeriesChart内

第6步:缺少了什么

快结束时,它将给您缺少的约束

I/flutter ( 4228):   constraints: BoxConstraints(w=120.0, 0.0<=h<=Infinity)
  • 通知: 0.0 <= h <=无穷大

  • 高度 不能为无穷大

步骤7:

  • 使用 SizedBox 扭曲源,以确保它是引发错误的原因,以查看是否解决了该问题

  • SizedBox

      

    具有指定大小的盒子。

         

    如果给了一个孩子,则此小部件将强制其孩子具有特定的宽度和/或高度(假定此小部件的父级允许使用值)。如果width或height为null,则此小部件将自行调整大小以匹配该维度中孩子的大小。

步骤8:

  1. TimeSeriesChart(子级)向Raw(父级)询问身高

  2. Raw(孩子)向列(父级)询问身高

  3. 该列不知道

  4. 不知道列的原因,因为默认情况下,行为是将其留给孩子决定自己的高度

  5. 但是我们可以告诉专栏,孩子们不知道,所以将他们扩展到可用空间

错误转储

I/flutter ( 4228): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4228): The following assertion was thrown during performLayout():
I/flutter ( 4228): FlutterError contained multiple error summaries.
I/flutter ( 4228): All FlutterError objects should have only a single short (one line) summary description of the
I/flutter ( 4228): problem that was detected.
I/flutter ( 4228): Malformed FlutterError:
I/flutter ( 4228):   RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I/flutter ( 4228):   This probably means that it is a render object that tries to be as big as possible, but it was put
I/flutter ( 4228):   inside another render object that allows its children to pick their own size.
I/flutter ( 4228):   RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I/flutter ( 4228):   This probably means that it is a render object that tries to be as big as possible, but it was put
I/flutter ( 4228):   inside another render object that allows its children to pick their own size.
I/flutter ( 4228):   The nearest ancestor providing an unbounded height constraint is: RenderFlex#d29e7 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
I/flutter ( 4228):     creator: Column ← [root]
I/flutter ( 4228):     parentData: <none>
I/flutter ( 4228):     constraints: BoxConstraints(w=320.0, h=480.0)
I/flutter ( 4228):     size: MISSING
I/flutter ( 4228):     direction: vertical
I/flutter ( 4228):     mainAxisAlignment: start
I/flutter ( 4228):     mainAxisSize: max
I/flutter ( 4228):     crossAxisAlignment: center
I/flutter ( 4228):     verticalDirection: down
I/flutter ( 4228):   The constraints that applied to the RenderCustomMultiChildLayoutBox were:
I/flutter ( 4228):     BoxConstraints(w=120.0, 0.0<=h<=Infinity)
I/flutter ( 4228):   The exact size it was given was:
I/flutter ( 4228):     Size(120.0, Infinity)
I/flutter ( 4228):   See https://flutter.dev/docs/development/ui/layout/box-constraints for more information.
I/flutter ( 4228):
I/flutter ( 4228): The malformed error has 2 summaries.
I/flutter ( 4228): Summary 1: RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I/flutter ( 4228): Summary 2: RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I/flutter ( 4228):
I/flutter ( 4228): This error should still help you solve your problem, however please also report this malformed error
I/flutter ( 4228): in the framework by filing a bug on GitHub:
I/flutter ( 4228):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 4228):
I/flutter ( 4228): When the exception was thrown, this was the stack:
I/flutter ( 4228): #0      new FlutterError.fromParts.<anonymous closure> (package:flutter/src/foundation/assertions.dart:540:9)
I/flutter ( 4228): #1      new FlutterError.fromParts (package:flutter/src/foundation/assertions.dart:543:6)
I/flutter ( 4228): #2      RenderBox.debugAssertDoesMeetConstraints.<anonymous closure> (package:flutter/src/rendering/box.dart:1966:28)
I/flutter ( 4228): #3      RenderBox.debugAssertDoesMeetConstraints (package:flutter/src/rendering/box.dart:2029:6)
I/flutter ( 4228): #4      RenderBox.size=.<anonymous closure> (package:flutter/src/rendering/box.dart:1740:7)
I/flutter ( 4228): #5      RenderBox.size= (package:flutter/src/rendering/box.dart:1742:6)
I/flutter ( 4228): #6      RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:355:5)
I/flutter ( 4228): #7      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 4228): #8      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:805:17)
I/flutter ( 4228): #9      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 4228): #10     RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:743:15)
I/flutter ( 4228): #11     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 4228): #12     RenderView.performLayout (package:flutter/src/rendering/view.dart:151:13)
I/flutter ( 4228): #13     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1496:7)
I/flutter ( 4228): #14     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:765:18)
I/flutter ( 4228): #15     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:346:19)
I/flutter ( 4228): #16     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
I/flutter ( 4228): #17     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:285:5)I/flutter ( 4228): #18     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1016:15)
I/flutter ( 4228): #19     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:958:9)
I/flutter ( 4228): #20     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:784:7)
I/flutter ( 4228): #29     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
I/flutter ( 4228): #30     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
I/flutter ( 4228): #31     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
I/flutter ( 4228): (elided 8 frames from package dart:async and package dart:async-patch)
I/flutter ( 4228):
I/flutter ( 4228): The following RenderObject was being processed when the exception was fired: RenderCustomMultiChildLayoutBox#e4ae0 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
I/flutter ( 4228):   creator: CustomMultiChildLayout ← TimeSeriesChart ← SimpleTimeSeriesChart ← Expanded ← Row ← Column
I/flutter ( 4228):     ← [root]
I/flutter ( 4228):   parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight (can use size)
I/flutter ( 4228):   constraints: BoxConstraints(w=120.0, 0.0<=h<=Infinity)
I/flutter ( 4228):   size: Size(120.0, Infinity)
I/flutter ( 4228): This RenderObject had the following descendants (showing up to depth 5):
I/flutter ( 4228):     child 1: RenderSemanticsGestureHandler#2034c NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 4228):       child: RenderPointerListener#aef29 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 4228):         child: ChartContainerRenderObject<DateTime>#b28fc NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 4228): ════════════════════════════════════════════════════════════════════════════════════════════════════

有关步骤8的更多信息

  • 现在我们知道该错误来自TimeSeriesChart小部件,因为它需要高度
  • 但是如果它没有高度,它将询问其父级,即行

  • 但行的高度没有固定限制,它将询问孩子

  • 但是孩子的身高没有固定值,它将询问父行

  • 但父级对其子级(行)没有固定的高度

答案 1 :(得分:1)

只需将Row包装在Expanded小部件中即可。

 Column(
    children: <Widget>[
      Container(height: 200, color: Colors.orange),
      Expanded(
        child: Row(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          Container(width: 200,color: Colors.orange),
          Expanded(child: SimpleTimeSeriesChart.withSampleData())
        ],
      )
     )
    ],
  )

说明是,Column创建时将为其子级提供 infinity约束,并且当您将任何子级包装在Flexible小部件中时,它将相应地执行空间(以及某些属性(如果有))。

Row的行为完全相同,但是是水平的。在这里,您可以将Expanded正确地添加到Row子级中,但是随后,它会尝试查找有多少不能扩展到自身大小,而{{1} }不知道,因为它距父(Row)的高度仍然是无限制的,这就是为什么您不需要使用Column甚至是Expanded的原因可用空间。