Flutter Web - 如何在 SingleChildScrollView -> Column 中使用 TabBarView?
Flutter Web - How to use a TabBarView inside a SingleChildScrollView -> Column?
我有一个带有 Column 的 SingleChildScrollView 作为子级,有很多子级,其中两个是 TabBar 和 TabBarView。 TabBar 呈现正常,但是当我添加 TabBarView 时出现错误:
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performResize():
Horizontal viewport was given unbounded height.
Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.
The relevant error-causing widget was:
TabBarView file:///C:/Users/user/Documents/FlutterProjects/singlechildscrollview/lib/main.dart:83:13
When the exception was thrown, this was the stack:
#0 RenderViewport.computeDryLayout.<anonymous closure> (package:flutter/src/rendering/viewport.dart:1418:15)
#1 RenderViewport.computeDryLayout (package:flutter/src/rendering/viewport.dart:1430:6)
#2 RenderBox.performResize (package:flutter/src/rendering/box.dart:2332:12)
#3 RenderObject.layout (package:flutter/src/rendering/object.dart:1758:9)
#4 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
...
The following RenderObject was being processed when the exception was fired: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... needs compositing
... parentData: <none> (can use size)
... constraints: BoxConstraints(0.0<=w<=568.0, 0.0<=h<=Infinity)
... size: MISSING
... axisDirection: right
... crossAxisDirection: down
... offset: _PagePosition#05511(range: null..null, viewport: null, ScrollableState, _ForceImplicitScrollPhysics -> PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#083c3, ScrollDirection.idle)
... anchor: 0.0
RenderObject: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=568.0, 0.0<=h<=Infinity)
size: MISSING
axisDirection: right
crossAxisDirection: down
offset: _PagePosition#05511(range: null..null, viewport: null, ScrollableState, _ForceImplicitScrollPhysics -> PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#083c3, ScrollDirection.idle)
anchor: 0.0
... center child: _RenderSliverFractionalPadding#c51bd NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: paintOffset=Offset(0.0, 0.0)
... constraints: MISSING
... geometry: null
... child: RenderSliverFillViewport#29be2 NEEDS-LAYOUT NEEDS-PAINT
... parentData: paintOffset=Offset(0.0, 0.0)
... constraints: MISSING
... geometry: null
... no children current live
====================================================================================================
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
RenderBox was not laid out: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'
我知道这个错误与 TabBarView 没有高度有关,我无法设置特定高度,因为每个选项卡的内容都是动态的或使用任何其他 ScrollView,我已经尝试将其包装到a Flexible with fit: FlexFit.loose 并设置为所有 Column 的 mainAxisSize: MainAxisSize.min 但它仍然不起作用。
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
late TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
/// Other widgets here...then
TabBar(
controller: tabController,
tabs: [
Tab(
child: Text(
"Tab 1",
style: TextStyle(
color: Colors.black
),
),
),
Tab(
child: Text(
"Tab 1",
style: TextStyle(
color: Colors.black
),
),
),
],
),
TabBarView(
controller: tabController,
children: [
/// Each content from each tab will have a dynamic height
Container(),
Container()
],
)
],
),
),
);
}
}
您可以使用此示例应用作为示例。简而言之,我将 TabBar
和 TabBarView
嵌套在 NestedScrollView
中,以占据屏幕的全尺寸。这样你就可以在 TabBarView
中有一个动态的 body
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyHomePage()));
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverToBoxAdapter(
child: TabBar(
controller: tabController,
labelColor: Colors.redAccent,
isScrollable: true,
tabs: [
Tab(
child: Text(
"Tab 1",
style: TextStyle(color: Colors.black),
),
),
Tab(
child: Text(
"Tab 1",
style: TextStyle(color: Colors.black),
),
),
],
),
),
];
},
body: Container(
child: TabBarView(
controller: tabController,
children: [
/// Each content from each tab will have a dynamic height
Container(),
Container()
],
),
),
),
);
}
}
我有一个带有 Column 的 SingleChildScrollView 作为子级,有很多子级,其中两个是 TabBar 和 TabBarView。 TabBar 呈现正常,但是当我添加 TabBarView 时出现错误:
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performResize():
Horizontal viewport was given unbounded height.
Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.
The relevant error-causing widget was:
TabBarView file:///C:/Users/user/Documents/FlutterProjects/singlechildscrollview/lib/main.dart:83:13
When the exception was thrown, this was the stack:
#0 RenderViewport.computeDryLayout.<anonymous closure> (package:flutter/src/rendering/viewport.dart:1418:15)
#1 RenderViewport.computeDryLayout (package:flutter/src/rendering/viewport.dart:1430:6)
#2 RenderBox.performResize (package:flutter/src/rendering/box.dart:2332:12)
#3 RenderObject.layout (package:flutter/src/rendering/object.dart:1758:9)
#4 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
...
The following RenderObject was being processed when the exception was fired: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... needs compositing
... parentData: <none> (can use size)
... constraints: BoxConstraints(0.0<=w<=568.0, 0.0<=h<=Infinity)
... size: MISSING
... axisDirection: right
... crossAxisDirection: down
... offset: _PagePosition#05511(range: null..null, viewport: null, ScrollableState, _ForceImplicitScrollPhysics -> PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#083c3, ScrollDirection.idle)
... anchor: 0.0
RenderObject: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=568.0, 0.0<=h<=Infinity)
size: MISSING
axisDirection: right
crossAxisDirection: down
offset: _PagePosition#05511(range: null..null, viewport: null, ScrollableState, _ForceImplicitScrollPhysics -> PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#083c3, ScrollDirection.idle)
anchor: 0.0
... center child: _RenderSliverFractionalPadding#c51bd NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: paintOffset=Offset(0.0, 0.0)
... constraints: MISSING
... geometry: null
... child: RenderSliverFillViewport#29be2 NEEDS-LAYOUT NEEDS-PAINT
... parentData: paintOffset=Offset(0.0, 0.0)
... constraints: MISSING
... geometry: null
... no children current live
====================================================================================================
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
RenderBox was not laid out: RenderViewport#4db57 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'
我知道这个错误与 TabBarView 没有高度有关,我无法设置特定高度,因为每个选项卡的内容都是动态的或使用任何其他 ScrollView,我已经尝试将其包装到a Flexible with fit: FlexFit.loose 并设置为所有 Column 的 mainAxisSize: MainAxisSize.min 但它仍然不起作用。
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
late TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
/// Other widgets here...then
TabBar(
controller: tabController,
tabs: [
Tab(
child: Text(
"Tab 1",
style: TextStyle(
color: Colors.black
),
),
),
Tab(
child: Text(
"Tab 1",
style: TextStyle(
color: Colors.black
),
),
),
],
),
TabBarView(
controller: tabController,
children: [
/// Each content from each tab will have a dynamic height
Container(),
Container()
],
)
],
),
),
);
}
}
您可以使用此示例应用作为示例。简而言之,我将 TabBar
和 TabBarView
嵌套在 NestedScrollView
中,以占据屏幕的全尺寸。这样你就可以在 TabBarView
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyHomePage()));
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverToBoxAdapter(
child: TabBar(
controller: tabController,
labelColor: Colors.redAccent,
isScrollable: true,
tabs: [
Tab(
child: Text(
"Tab 1",
style: TextStyle(color: Colors.black),
),
),
Tab(
child: Text(
"Tab 1",
style: TextStyle(color: Colors.black),
),
),
],
),
),
];
},
body: Container(
child: TabBarView(
controller: tabController,
children: [
/// Each content from each tab will have a dynamic height
Container(),
Container()
],
),
),
),
);
}
}