我正在尝试创建一个没有AppBar的标签栏布局屏幕。我已经在这个链接上提到了解决方案:how to create the tab bar without app bar in flutter?但它对我不起作用。当我将TabBar放在appbar:
参数中时,我的屏幕就像这样:
我的TabBar已经移动到状态栏下方的左上角,并且它全部挤在一个角落里。这几乎就好像根本就没有。
当我使用AppBar类但只传递bottom:
参数时会发生以下情况:
TabBar顶部有一个丑陋的空间,显然是AppBar标题。这是我的代码:
return new Scaffold(
appBar: new TabBar(
tabs: widget._tabs.map((_Page page){
return Text(page.tabTitle);
}).toList(),
controller: _tabController,
isScrollable: true,
),
backgroundColor: Colors.white,
body: new TabBarView(
controller: _tabController,
children: widget._tabs.map((_Page page){
return new SafeArea(
top:false,
bottom: false,
child: (page.page == Pages.cart?new CartHomeScreen():_lunchesLayout())
);
}).toList()
),
);
如何在没有顶部空间的情况下使用TabBar,是否可以使两个标签项及其指示符伸展并填充侧边空间?
答案 0 :(得分:22)
你的第一个截图实际上显示它工作得很好 - 问题是“好”并不是你所期望的。对于标签栏,默认文本颜色为白色,因此您的标签不显示,而只是显示底线,这是您在左上角看到的。此外,TabBar已经是一个首选的大小小部件,但它与AppBar的高度不同,所以如果这就是你想要的,它看起来就不像了。
这是一个让它看起来像应用栏的例子。 kToolbarHeight
与AppBar使用的常量相同。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => new MyAppState();
}
class MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'msc',
home: new DefaultTabController(
length: 2,
child: new Scaffold(
appBar: new PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: new Container(
color: Colors.green,
child: new SafeArea(
child: Column(
children: <Widget>[
new Expanded(child: new Container()),
new TabBar(
tabs: [new Text("Lunches"), new Text("Cart")],
),
],
),
),
),
),
body: new TabBarView(
children: <Widget>[
new Column(
children: <Widget>[new Text("Lunches Page")],
),
new Column(
children: <Widget>[new Text("Cart Page")],
)
],
),
),
),
);
}
}
结果如下:
答案 1 :(得分:6)
我从rmtmckenzie获取了代码,但只创建了一个没有实质性应用程序的小部件
return new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: new Container(
height: 50.0,
child: new TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car,color: Colors.grey,)),
Tab(icon: Icon(Icons.directions_transit,color: Colors.grey)),
Tab(icon: Icon(Icons.directions_bike,color: Colors.grey)),
],
),
),
),
body: TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
);
答案 2 :(得分:4)
您不需要使用 appBar
属性:
Scaffold(
body: Column(
children: [
TabBar( // <-- Your TabBar
tabs: [
Tab(icon: Icon(Icons.camera)),
Tab(icon: Icon(Icons.settings)),
],
),
Expanded(
child: TabBarView( // <-- Your TabBarView
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
),
),
],
),
)
答案 3 :(得分:2)
这很简单,您所需要提供的只是height
到您的TabView
。
这是一个简单的例子。您可以使用DefaultTabController
或TabController
。为了完全可定制,我将使用TabController
。
_getTabBar
函数返回选项卡列表。
TabBar _getTabBar() {
return TabBar(
tabs: <Widget>[
Tab(icon: Icon(Icons.home, color: Colors.redAccent)),
Tab(icon: Icon(Icons.settings, color: Colors.redAccent)),
],
controller: tabController,
);
}
_getTabBarView
将小部件列表作为输入参数,并创建一个选项卡视图。
TabBarView _getTabBarView(tabs) {
return TabBarView(
children: tabs,
controller: tabController,
);
}
SafeArea
用于将内容移动到状态栏下方。 _getTabBarView
用Container
包装,以便我们可以分配高度。这是分配高度的一种方式,您也可以使用其他方式。
这是完整的代码,包装在MaterialApp
中,您将获得完全可自定义的标签栏和视图。生命周期方法用于创建和处理TabController
import 'package:flutter/material.dart';
class TabControllerScreen extends StatefulWidget {
@override
_TabControllerScreenState createState() => _TabControllerScreenState();
}
class _TabControllerScreenState extends State<TabControllerScreen> with SingleTickerProviderStateMixin {
TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
TabBar _getTabBar() {
return TabBar(
tabs: <Widget>[
Tab(icon: Icon(Icons.home, color: Colors.redAccent)),
Tab(icon: Icon(Icons.settings, color: Colors.redAccent)),
],
controller: tabController,
);
}
TabBarView _getTabBarView(tabs) {
return TabBarView(
children: tabs,
controller: tabController,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
_getTabBar(),
Container(
height: 100,
child: _getTabBarView(
<Widget>[
Icon(Icons.home),
Icon(Icons.settings),
],
),
)
],
),
),
);
}
}
答案 4 :(得分:2)
按照下面的代码
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Text(
"Tabbar with out Appbar",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
),
color: Colors.blue,
),
TabBar(
unselectedLabelColor: Colors.black,
labelColor: Colors.red,
tabs: [
Tab(
text: '1st tab',
),
Tab(
text: '2 nd tab',
)
],
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
),
Expanded(
child: TabBarView(
children: [
Container(child: Center(child: Text('people'))),
Text('Person')
],
controller: _tabController,
),
),
],
),
),
);
}
}
查看结果
答案 5 :(得分:1)
根据 CopsOnRoad 的回答,我创建了一个隐藏的 TabBar,如下所示:
Scaffold(
body: Column(
children: [
TabBar( // <-- Hidden TabBar
indicator: BoxDecoration(),
tabs: [
SizedBox.shrink(),
SizedBox.shrink(),
],
),
Expanded(
child: TabBarView( // <-- Your TabBarView
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
),
),
],
),
)
答案 6 :(得分:0)
尝试将TabBar放在flexibleSpace
道具的AppBar中。
答案 7 :(得分:0)
仅使用flexiblespace属性而不是appBar的底部属性。 全部都在safeArea小部件中,您可以添加一些垂直填充。
home: SafeArea(
top: true,
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
flexibleSpace: TabBar(
tabs: [
Tab(icon: Icon(Icons.1)),
Tab(icon: Icon(Icons.2)),
Tab(icon: Icon(Icons.3)),
],
),
),
body: TabBarView(
children: [
Icon(Icons.1),
Icon(Icons.2),
Icon(Icons.3),
],
),
),
),
),
)
答案 8 :(得分:0)
只需在toolbarHeight
小部件中使用AppBar
值的kMinInteractiveDimension
属性,如下所示:
Scaffold(
appBar: AppBar(
toolbarHeight: kMinInteractiveDimension,
bottom: TabBar(
controller: _tabController,
tabs: [], // your tab bars
),
),
body: TabBarView(
controller: _tabController,
children: [], // your tab views
),
);
答案 9 :(得分:0)
直接在TabBar
属性中使用appBar
:
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: TabBar(
tabs: [
Tab(icon: Icon(Icons.call)),
Tab(icon: Icon(Icons.message)),
],
),
body: TabBarView(
children: [
Center(child: Text('Call')),
Center(child: Text('Message')),
],
),
),
);
}