簡體   English   中英

嵌套行/列中的顫振擴展圖表

[英]Flutter expanded chart in nested row / column

我正在嘗試從charts_flutter 包中獲取圖表以擴展以填充可用空間,當它位於列內的行內時。 我花了幾個小時試圖做到這一點,但我一定錯過了一些東西! 這在視覺上是我想要實現的:

在此處輸入圖片說明

這是一個最小的工作示例。 我一定已經嘗試了上百種擴展、靈活、主軸大小、橫軸對齊等組合,但我似乎無法找到正確的組合。 目前底部溢出無限像素, object was given an infinite size during layout 這個open issue ,不知道有沒有關系,也沒有答案。 我只需要runApp的一些代碼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);
}

**在第 8 步了解原因 - 向下滾動👇 **

問題

我正在嘗試從 charts_flutter 包中獲取圖表以擴展以填充可用空間

錯誤證據

對象在布局期間被賦予無限大小

解決方案

用 Expanded 包裹行

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

截屏

在此處輸入圖片說明

筆記:

  • 😎 , 感謝提供最少的代碼

完整的工作代碼

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<=Infinity

  • 高度不能是無窮大

第 7 步:

  • 使用SizedBox扭曲源以確保它是引發錯誤的原因,看看它是否解決了它

  • 大小盒

    具有指定尺寸的盒子。

    如果給定一個孩子,這個小部件會強制它的孩子有一個特定的寬度和/或高度(假設這個小部件的父級允許值)。 如果寬度或高度為空,則此小部件將調整自身大小以匹配該維度中孩子的大小。

第 8 步:

  1. TimeSeriesChart(child) 向 Raw(parent) 詢問身高

  2. Raw(child) 向 Column(parent) 詢問身高

  3. 列不知道

  4. 為什么 Column 不知道,因為默認情況下,它會讓孩子們決定他們自己的高度

  5. 但是我們可以告訴 Column 孩子們不知道所以將它們擴展到可用空間

錯誤轉儲

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 小部件,因為它需要高度
  • 但如果它沒有高度,它會詢問它的父級,即行

  • 但這一行沒有固定的高度,它會問孩子們

  • 但孩子們沒有固定的高度,它會問行父母

  • 但是父級沒有固定的高度給它的子級(行)

只需將您的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在創建時將為其子項提供無限約束,並且當您將任何子項包裝在一個Flexible小部件中時,它將根據可用空間(以及一些屬性,如果有)采取相應的行動。

Row行為方式完全相同,但是是水平的。 在這里,您正確地將Expanded添加到Row子項,但是,它會嘗試找出它自身無法擴展到多少大小,而Row不知道,因為它與父級( Column )的高度仍然是無限的,這就是為什么如果您不需要適應可用空間,您應該使用Expanded甚至是Flexible的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM