TabBar中的TabBarView占用剩余空间

问题描述 投票:0回答:1

我一直在我的 flutter 应用程序中使用

TabBar()
,它一直在工作,除非我发现当屏幕尺寸改变时我的
TabBarView()
会变得混乱。 在遵循this问题后,我发现我的问题的解决方案是
Expanded()
对于
TabBarView()
。我已经尽力了,但我得到的只是关于渲染数据的很多错误。

       ⡿flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: RenderFlex children have non-zero flex but incoming height constraints are unbounded.
       ⣟flutter: When a column is in a parent that does not provide a finite height constraint, for example if it is
flutter: in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
flutter: flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
flutter: space in the vertical direction.
flutter: These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
flutter: cannot simultaneously expand to fit its parent.
flutter: Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
flutter: children (using Flexible rather than Expanded). This will allow the flexible children to size
flutter: themselves to less than the infinite remaining space they would otherwise be forced to take, and
flutter: then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
flutter: constraints provided by the parent.
flutter: If this message did not help you determine the problem, consider using debugDumpRenderTree():
flutter:   https://flutter.dev/debugging/#rendering-layer
flutter:   http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
flutter: The affected RenderFlex is:
flutter:   RenderFlex#bc077 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT(creator: Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ← ⋯, parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size), constraints: BoxConstraints(w=375.0, 0.0<=h<=Infinity), size: MISSING, direction: vertical, mainAxisAlignment: start, mainAxisSize: min, crossAxisAlignment: start, textDirection: ltr, verticalDirection: down)
flutter: The creator information is set to:
flutter:   Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ←
flutter:   CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
flutter:   _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
flutter:   PhysicalModel ← ⋯
flutter: The nearest ancestor providing an unbounded width constraint is: RenderFlex#0807f relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-PAINT:
flutter:   creator: Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ←
flutter:     AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#4f100 ink
flutter:     renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ←
flutter:     AnimatedPhysicalModel ← Material ← ⋯
flutter:   parentData: offset=Offset(0.0, 0.0); id=_ScaffoldSlot.body (can use size)
flutter:   constraints: BoxConstraints(0.0<=w<=375.0, 0.0<=h<=591.0)
flutter:   size: MISSING
flutter:   direction: vertical
flutter:   mainAxisAlignment: start
flutter:   mainAxisSize: min
flutter:   crossAxisAlignment: stretch
flutter:   verticalDirection: down
flutter: See also: https://flutter.dev/layout/
flutter: If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
flutter:   https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      RenderFlex.performLayout.<anonymous closure> (package:flutter/src/rendering/flex.dart:691:11)
flutter: #1      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:717:10)
flutter: #2      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #3      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:743:15)
flutter: #4      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #5      MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
flutter: #6      _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:443:7)
flutter: #7      MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
flutter: #8      RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
flutter: #9      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #10     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #11     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #12     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #13     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1214:11)
flutter: #14     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #15     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #16     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #17     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #18     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #19     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #20     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #21     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
flutter: #22     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #23     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #24     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #25     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #26     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #27     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #28     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #29     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #30     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #31     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #32     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #33     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #34     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3067:13)
flutter: #35     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #36     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
flutter: #37     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #38     __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #39     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #40     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #41     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #42     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #43     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #44     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #45     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #46     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #47     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #48     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #49     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #50     RenderView.performLayout (package:flutter/src/rendering/view.dart:151:13)
flutter: #51     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1497:7)
flutter: #52     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:766:18)
flutter: #53     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:346:19)
flutter: #54     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
flutter: #55     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:285:5)
flutter: #56     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
flutter: #57     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9)
flutter: #58     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:773:7)
flutter: #60     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
flutter: #61     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
flutter: #62     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:171:12)
flutter: (elided one frame from package dart:async-patch)
flutter:
flutter: The following RenderObject was being processed when the exception was fired: RenderFlex#bc077 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT:
flutter:   creator: Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ←
flutter:     CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
flutter:     _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
flutter:     PhysicalModel ← ⋯
       ⣯flutter:   parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
flutter:   constraints: BoxConstraints(w=375.0, 0.0<=h<=Infinity)
flutter:   size: MISSING
flutter:   direction: vertical
flutter:   mainAxisAlignment: start
flutter:   mainAxisSize: min
flutter:   crossAxisAlignment: start
flutter:   textDirection: ltr
flutter:   verticalDirection: down
flutter: This This RenderObject had the following descendants (showing up to depth 5):
flutter:     child 1: RenderPadding#ec776 relayoutBoundary=up3 NEEDS-PAINT
flutter:       child: RenderDecoratedBox#82c7d relayoutBoundary=up4 NEEDS-PAINT
flutter:         child: RenderPadding#47def relayoutBoundary=up5 NEEDS-PAINT
flutter:           child: RenderCustomPaint#d3174 relayoutBoundary=up6 NEEDS-PAINT
flutter:             child: _TabLabelBarRenderer#1dbbb relayoutBoundary=up7 NEEDS-PAINT
flutter:     child 2: _RenderScrollSemantics#ab273 NEEDS-LAYOUT NEEDS-PAINT
flutter:       child: RenderPointerListener#85f41 NEEDS-LAYOUT NEEDS-PAINT
flutter:         child: RenderSemanticsGestureHandler#dfb17 NEEDS-LAYOUT NEEDS-PAINT
flutter:           child: RenderPointerListener#36472 NEEDS-LAYOUT NEEDS-PAINT
flutter:             child: RenderSemanticsAnnotations#0d0f0 NEEDS-LAYOUT NEEDS-PAINT
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: RenderBox was not laid out: RenderFlex#bc077 relayoutBoundary=up2 NEEDS-PAINT
flutter: Another exception was thrown: RenderBox was not laid out: RenderFlex#0807f relayoutBoundary=up1 NEEDS-PAINT
flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.

现在让您了解我一直在做的事情是,我有一个小部件类,在其中定义了我的

TabBar
并且我在不同的地方使用它。

这是我的 TabBar 类小部件:

@override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          margin: EdgeInsets.only(left: 16.0, right: 16.0),
          decoration: BoxDecoration(
            color: Colors.white.withOpacity(0.0),
            border: Border(bottom: BorderSide(color: Colors.grey, width: 0.5))),
          child: TabBar(
            unselectedLabelColor: Colors.grey,
            unselectedLabelStyle: TextStyle().copyWith(fontSize: 16.0, fontWeight: FontWeight.normal),
            labelColor: Color.fromRGBO(253, 92, 99, 1),
            labelStyle: TextStyle().copyWith(fontSize: 16.0, fontWeight: FontWeight.bold),
            indicatorColor: Color.fromRGBO(253, 92, 99, 1),
            indicatorWeight: widget.indicatorWeight,
            controller: _controller,
            tabs: [
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childOneHeader, style: TextStyle(fontSize: 15.0)),
                )
              ),
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childTwoHeader, style: TextStyle(fontSize: 15.0)),
                )
              ),
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childThreeHeader, style: TextStyle(fontSize: 15.0)),
                )
              )
            ]
          )
        ),
        Expanded(
          //height: widget.layoutHeight,
          child: new TabBarView(
            controller: _controller,
            children: <Widget>[
              widget.childOne,
              widget.childTwo,
              widget.childThree
            ],
          )
        )
      ]
    );

带有

widget.
的数据来自其构造函数。

现在我一直在我的页面中使用这个,其中

ListView()
代表我的
TabBarView() children
,所以我只从他们那里传递它。

使用TabBar代码的类:

body: Column(
   mainAxisSize: MainAxisSize.min,
   crossAxisAlignment: CrossAxisAlignment.stretch,
   children: <Widget>[
     Text('Heading'),
     Container(),
     TabWidget(
            indicatorWeight: 1.0,
            childOneHeader: 'Title 1',
            childTwoHeader: 'Title 2',
            childThreeHeader: 'Title 3',
            childOne: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
                [Container(
                  child: errorWidget,
                )] 
                : this.getOffersWidgets()
            ),
            childTwo: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
              [Container(
                child: errorWidget,
              )] 
              : this.getBarWidgets()
            ),
            childThree: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
              [Container(
                child: errorWidget,
              )]
              : this.getEventWidget()
            )
          )
   ]
);

我已经尽力了,但还是没能成功。我得到的只是一张空白页,没有其他任何东西。请在这件事上给予我帮助。谢谢:)

解决方案:

既然我找到了出路,所以我想以后看到这个问题的朋友也会从这个问题中受益。

如果您想看一下,这是答案的链接:我的问题的解决方案

在使用 tabbarcode 的课程中,将

TabWidget
包裹在
Expanded()
内,其余部分相同,你的工作就完成了。

body: Column(
   mainAxisSize: MainAxisSize.min,
   crossAxisAlignment: CrossAxisAlignment.stretch,
   children: <Widget>[
     Text('Heading'),
     Container(),
     Expanded(
      child: TabWidget(//your content goes here)
     )

特别感谢MFARKAN

请注意,永远不要在 ListView() 或任何可滚动小部件中使用 Expanded() 或Flexible(),因为它们需要有限的高度。在内容中使用它,但不能用于 Expanded()

谢谢大家! :)

dart flutter uitabbar
1个回答
3
投票

重申关闭线程的解决方案。正如 GitHub 上发布的问题单中提到的,

TabBarView
需要渲染有限的高度。这可以通过使用 Expanded widget 来实现,如发布的错误日志和此 GitHub 线程

中发布的解决方案中的建议

这是您可以尝试的最小重现

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: const TabWidget(),
    );
  }
}

class TabWidget extends StatefulWidget {
  const TabWidget({super.key});

  @override
  TabWidgetState createState() => TabWidgetState();
}

class TabWidgetState extends State<TabWidget>
    with SingleTickerProviderStateMixin {
  late TabController _controller;
  @override
  void initState() {
    super.initState();
    _controller = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 10.0),
      child: Column(
        children: <Widget>[
          TabBar(
            labelColor: Colors.black,
            indicatorColor: Colors.blue,
            controller: _controller,
            tabs: const <Widget>[
              Tab(
                text: 'Tab 1',
              ),
              Tab(
                text: 'Tab 2',
              ),
              Tab(
                text: 'Tab 3',
              ),
            ],
          ),
          Expanded(
            child: TabBarView(
              controller: _controller,
              children: const <Widget>[
                Center(
                  child: Text('Tab View 1'),
                ),
                Center(
                  child: Text('Tab View 2'),
                ),
                Center(
                  child: Text('Tab View 3'),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

应用程序的外观

© www.soinside.com 2019 - 2024. All rights reserved.