如何在属于另一个选项卡的页面中添加选项卡
How to have tabs in a page which is part of another tab
我的页面布局如下:
底部选项卡是使用 BottomNavigationBar
在 Scaffold
对象中创建的,它允许在页面之间切换。在其中一个页面 "Profile" 页面中,我想在用户头像下显示另一个选项卡栏。到目前为止,我已经想出了以下代码,但不知道如何继续:
class ProfilePageState extends State<ProfilePage> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = new TabController(vsync: this, length: 3);
super.initState();
}
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Container(
color: Colors.lightBlue,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Center(
child: CircleAvatar(
backgroundImage: _getAvatarImage(),
maxRadius: 60.0,
)),
),
Padding(
padding: EdgeInsets.only(top: 20.0),
child: Center(child: Text(user == null ? "" : user.name, style: TextStyle(color: Colors.white),))),
],
),
),
Material(
color: Colors.lightBlueAccent,
child: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
),
TabBarView(
controller: _tabController,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
)
],
);
}
我在个人资料页面中出现以下异常:
I/flutter (13456): The following assertion was thrown during performResize():
I/flutter (13456): Horizontal viewport was given unbounded height.
I/flutter (13456): Viewports expand in the cross
axis to fill their container and constrain their children to match
I/flutter (13456): their extent in the cross axis. In this case, a
horizontal viewport was given an unlimited amount of I/flutter
(13456): vertical space in which to expand.
错误是因为没有固定的视口来完成布局。
鉴于您绘制的布局和 ListView
作为根小部件,我假设您希望内容滚动。在这种情况下,您可以按如下方式使用 NestedScrollView
和 SliverAppBar
:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Profile Page',
home: ProfilePage(),
);
}
}
class ProfilePage extends StatefulWidget {
ProfilePage({Key key}) : super(key: key);
@override
ProfilePageState createState() => ProfilePageState();
}
class ProfilePageState extends State<ProfilePage>
with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = TabController(vsync: this, length: 3);
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
pinned: true,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
flexibleSpace: FlexibleSpaceBar(
background: SafeArea(
child: Container(
color: Colors.lightBlue,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Center(
child: CircleAvatar(
// backgroundImage: _getAvatarImage(),
maxRadius: 60.0,
)),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Center(
child: Text(
'User name',
style: TextStyle(color: Colors.white),
))),
],
),
),
),
),
centerTitle: false,
title: Text('Title'),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
)
// ],
);
}
}
我的页面布局如下:
底部选项卡是使用 BottomNavigationBar
在 Scaffold
对象中创建的,它允许在页面之间切换。在其中一个页面 "Profile" 页面中,我想在用户头像下显示另一个选项卡栏。到目前为止,我已经想出了以下代码,但不知道如何继续:
class ProfilePageState extends State<ProfilePage> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = new TabController(vsync: this, length: 3);
super.initState();
}
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Container(
color: Colors.lightBlue,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Center(
child: CircleAvatar(
backgroundImage: _getAvatarImage(),
maxRadius: 60.0,
)),
),
Padding(
padding: EdgeInsets.only(top: 20.0),
child: Center(child: Text(user == null ? "" : user.name, style: TextStyle(color: Colors.white),))),
],
),
),
Material(
color: Colors.lightBlueAccent,
child: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
),
TabBarView(
controller: _tabController,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
)
],
);
}
我在个人资料页面中出现以下异常:
I/flutter (13456): The following assertion was thrown during performResize():
I/flutter (13456): Horizontal viewport was given unbounded height.
I/flutter (13456): Viewports expand in the cross
axis to fill their container and constrain their children to match
I/flutter (13456): their extent in the cross axis. In this case, a
horizontal viewport was given an unlimited amount of I/flutter
(13456): vertical space in which to expand.
错误是因为没有固定的视口来完成布局。
鉴于您绘制的布局和 ListView
作为根小部件,我假设您希望内容滚动。在这种情况下,您可以按如下方式使用 NestedScrollView
和 SliverAppBar
:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Profile Page',
home: ProfilePage(),
);
}
}
class ProfilePage extends StatefulWidget {
ProfilePage({Key key}) : super(key: key);
@override
ProfilePageState createState() => ProfilePageState();
}
class ProfilePageState extends State<ProfilePage>
with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = TabController(vsync: this, length: 3);
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
pinned: true,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
flexibleSpace: FlexibleSpaceBar(
background: SafeArea(
child: Container(
color: Colors.lightBlue,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Center(
child: CircleAvatar(
// backgroundImage: _getAvatarImage(),
maxRadius: 60.0,
)),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Center(
child: Text(
'User name',
style: TextStyle(color: Colors.white),
))),
],
),
),
),
),
centerTitle: false,
title: Text('Title'),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
)
// ],
);
}
}