在 flutter 中使用 TabBarView 获取 'Horizontal viewport was given unbounded height.'
Getting 'Horizontal viewport was given unbounded height.' with TabBarView in flutter
我正在尝试制作个人资料页面,其中用户信息位于顶部。然后在其下方有一个选项卡视图以显示不同的视图。
这是我目前正在使用的代码,当我取出 TabBarView
时它不会出错,如果我将 TabBarView
包装在 Expanded
出现错误 RenderFlex children have non-zero flex but incoming height constraints are unbounded.
。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
CircleAvatar(
minRadius: 45.0,
backgroundImage: NetworkImage(
'https://www.ienglishstatus.com/wp-content/uploads/2018/04/Anonymous-Whatsapp-profile-picture.jpg'),
),
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Testing Name',
style: TextStyle(
fontSize: 22.0,
color: Colors.grey.shade800,
),
),
Text(
'@testing_username',
style: TextStyle(
fontSize: 13.0,
color: Colors.grey.shade800,
),
),
],
),
),
],
),
),
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
TabBar(
tabs: <Widget>[
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
],
),
TabBarView(
children: <Widget>[
Container(
color: Colors.grey,
),
Container(
color: Colors.green,
),
Container(
color: Colors.purple,
),
],
),
],
),
)
],
),
);
}
我确实尝试了 this 的变体,但无法正常工作。
错误描述清楚,TabBarView 没有限定高度。父小部件也没有限制高度。所以,Expanded widget 不会解决这个问题。
编辑: 以下解决方案针对上述问题(带列)。在一般情况下,使用带 shrinkWrap: true
的 ListView。(或任何其他带有 shrinkWrap 的小部件) 正如@Konstantin Kozirev 正确提到的那样,shrinkWrap 会导致一些性能问题。寻找更好的更新解决方案。
有一些选项:
第一个解决方案:
用 SizedBox 或 AspectRatio 等高度有限的小部件包裹父小部件(列)。然后像这样使用扩展小部件:
Expanded(
child: TabBarView(...),
)
第二个解:
在 TabBarView 本身上使用像 SizedBox 或 AspectRatio 这样的有界小部件:
SizedBox(
height: 300.0,
child: TabBarView(...),
)
注意如果高度不是静态的,也可以动态计算高度。
我通过在 Container
中添加 TabBar
和在 Expanded
中添加 TabBarView
来解决它:
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
Container(child: TabBar(..)),
Expanded(child: TabBarView(..)),
],
),
);
基于@Yamin 的回答,我使用如下所示的 SizeBox 来获取整页
SizedBox.expand(
child: TabBarView(),
)
或任何其他尺寸:
SizedBox(
height: height:MediaQuery.of(context).size.height // or every other size ,
child: TabBarView(),
)
尝试使用 IndexedStack
而不是 TabBarView
我试过 Expanded
, shrinkWrap = true
, ...
但没有人工作正常
试试例子。
示例:
class Product extends StatefulWidget {
@override
_ProductState createState() => _ProductState();
}
class _ProductState extends State<Product> with SingleTickerProviderStateMixin {
TabController tabController;
int selectedIndex = 0;
@override
void initState() {
super.initState();
tabController = TabController(length: 5, vsync: this, initialIndex: 0);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
initialIndex: 0,
child: Scaffold(
body: ListView(
shrinkWrap: true,
children: [
TabBar(
tabs: <Widget>[
Tab(
text: 'one',
),
Tab(
text: 'two',
),
Tab(
text: 'three',
),
],
controller: tabController,
onTap: (index) {
setState(() {
selectedIndex = index;
tabController.animateTo(index);
});
},
),
IndexedStack(
children: <Widget>[
Visibility(
child: Text('test1'),
maintainState: true,
visible: selectedIndex == 0,
),
Visibility(
child: Text('test2'),
maintainState: true,
visible: selectedIndex == 1,
),
Visibility(
child: Text('test3'),
maintainState: true,
visible: selectedIndex == 2,
),
],
index: selectedIndex,
),
],
),
),
);
}
}
特别感谢@arbalest
我正在尝试制作个人资料页面,其中用户信息位于顶部。然后在其下方有一个选项卡视图以显示不同的视图。
这是我目前正在使用的代码,当我取出 TabBarView
时它不会出错,如果我将 TabBarView
包装在 Expanded
出现错误 RenderFlex children have non-zero flex but incoming height constraints are unbounded.
。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
CircleAvatar(
minRadius: 45.0,
backgroundImage: NetworkImage(
'https://www.ienglishstatus.com/wp-content/uploads/2018/04/Anonymous-Whatsapp-profile-picture.jpg'),
),
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Testing Name',
style: TextStyle(
fontSize: 22.0,
color: Colors.grey.shade800,
),
),
Text(
'@testing_username',
style: TextStyle(
fontSize: 13.0,
color: Colors.grey.shade800,
),
),
],
),
),
],
),
),
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
TabBar(
tabs: <Widget>[
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
],
),
TabBarView(
children: <Widget>[
Container(
color: Colors.grey,
),
Container(
color: Colors.green,
),
Container(
color: Colors.purple,
),
],
),
],
),
)
],
),
);
}
我确实尝试了 this 的变体,但无法正常工作。
错误描述清楚,TabBarView 没有限定高度。父小部件也没有限制高度。所以,Expanded widget 不会解决这个问题。
编辑: 以下解决方案针对上述问题(带列)。在一般情况下,使用带 正如@Konstantin Kozirev 正确提到的那样,shrinkWrap 会导致一些性能问题。寻找更好的更新解决方案。shrinkWrap: true
的 ListView。(或任何其他带有 shrinkWrap 的小部件)
有一些选项:
第一个解决方案:
用 SizedBox 或 AspectRatio 等高度有限的小部件包裹父小部件(列)。然后像这样使用扩展小部件:
Expanded(
child: TabBarView(...),
)
第二个解:
在 TabBarView 本身上使用像 SizedBox 或 AspectRatio 这样的有界小部件:
SizedBox(
height: 300.0,
child: TabBarView(...),
)
注意如果高度不是静态的,也可以动态计算高度。
我通过在 Container
中添加 TabBar
和在 Expanded
中添加 TabBarView
来解决它:
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
Container(child: TabBar(..)),
Expanded(child: TabBarView(..)),
],
),
);
基于@Yamin 的回答,我使用如下所示的 SizeBox 来获取整页
SizedBox.expand(
child: TabBarView(),
)
或任何其他尺寸:
SizedBox(
height: height:MediaQuery.of(context).size.height // or every other size ,
child: TabBarView(),
)
尝试使用 IndexedStack
而不是 TabBarView
我试过 Expanded
, shrinkWrap = true
, ...
但没有人工作正常
试试例子。
示例:
class Product extends StatefulWidget {
@override
_ProductState createState() => _ProductState();
}
class _ProductState extends State<Product> with SingleTickerProviderStateMixin {
TabController tabController;
int selectedIndex = 0;
@override
void initState() {
super.initState();
tabController = TabController(length: 5, vsync: this, initialIndex: 0);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
initialIndex: 0,
child: Scaffold(
body: ListView(
shrinkWrap: true,
children: [
TabBar(
tabs: <Widget>[
Tab(
text: 'one',
),
Tab(
text: 'two',
),
Tab(
text: 'three',
),
],
controller: tabController,
onTap: (index) {
setState(() {
selectedIndex = index;
tabController.animateTo(index);
});
},
),
IndexedStack(
children: <Widget>[
Visibility(
child: Text('test1'),
maintainState: true,
visible: selectedIndex == 0,
),
Visibility(
child: Text('test2'),
maintainState: true,
visible: selectedIndex == 1,
),
Visibility(
child: Text('test3'),
maintainState: true,
visible: selectedIndex == 2,
),
],
index: selectedIndex,
),
],
),
),
);
}
}
特别感谢@arbalest