Flutter TabBar没有AppBar

时间:2018-05-30 16:11:34

标签: dart flutter

我正在尝试创建一个没有AppBar的标签栏布局屏幕。我已经在这个链接上提到了解决方案:how to create the tab bar without app bar in flutter?但它对我不起作用。当我将TabBar放在appbar:参数中时,我的屏幕就像这样:

enter image description here

我的TabBar已经移动到状态栏下方的左上角,并且它全部挤在一个角落里。这几乎就好像根本就没有。

当我使用AppBar类但只传递bottom:参数时会发生以下情况:

enter image description here

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,是否可以使两个标签项及其指示符伸展并填充侧边空间?

10 个答案:

答案 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")],
              )
            ],
          ),
        ),
      ),
    );
  }
}

结果如下:

Screenshot showing tabbed app bar

答案 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

这是一个简单的例子。您可以使用DefaultTabControllerTabController。为了完全可定制,我将使用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用于将内容移动到状态栏下方。 _getTabBarViewContainer包装,以便我们可以分配高度。这是分配高度的一种方式,您也可以使用其他方式。

这是完整的代码,包装在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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

查看结果

enter image description here

答案 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')),
        ],
      ),
    ),
  );
}