简体   繁体   English

在 Flutter 中为选项卡添加底部边框

[英]Add bottom border of to tabs in Flutter

What I'm trying to do is adding a bottom border of tabBar, so it will be under tabs title and above the indicatorColor and for both active and Inactive tabs, just like the attached image.我想要做的是添加 tabBar 的底部边框,因此它将位于选项卡标题下方和指示器颜色上方以及活动和非活动选项卡,就像附加的图像一样。

Red line is what I am trying to add, green line is the indicatorColor.红线是我要添加的,绿线是指标颜色。

Note, usually I do this for appBar using 'bottom' but here bottom is reserved to the TabBar .请注意,通常我使用 'bottom' 为 appBar 执行此操作,但这里的底部保留给 TabBar

Is this possible?这可能吗?

Thanks a lot非常感谢

Flutter 选项卡屏幕

Try to set appBar border :尝试设置 appBar 边框:

appBar: AppBar(
    shape: Border(bottom: BorderSide(color: Colors.red)),
     .... 

You can set the AppBar shape property as abdulrahmanAbdullah says.您可以像 abdulrahmanAbdullah 所说的那样设置 AppBar shape属性。 But if you strictly need the border above the indicator, you can put it inside of each tab bar item.但是,如果您严格需要指示器上方的边框,则可以将其放在每个选项卡栏项目内。 Here's one take on it:这是一个看法:

import 'package:flutter/material.dart';

void main() {
  runApp(TabBarDemo());
}



class TabBarDemo extends StatelessWidget {

  Widget _createTab(String text) {
    return Tab(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
            child: Container(
              child: Center(child: Text(text)),
              decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black)))
            )
          ),
        ]
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.white,
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            elevation: 0,
            bottom: TabBar(
              labelPadding: EdgeInsets.all(0),
              tabs: [
                _createTab("Tab 1"),
                _createTab("Tab 2"),
                _createTab("Tab 3"),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  }
}

I managed to do that using ' flexibleSpace ' property instead 'bottom' property, as flexibleSpace can have any widget not only 'PreferredSizeWidget' like bottom.我设法使用“灵活空间”属性而不是“底部”属性来做到这一点,因为灵活空间可以拥有任何小部件,而不仅仅是像底部这样的“PreferredSizeWidget”。

So I gave a Column to the flexibleSpace, then I was able to put TabBar and the container inside that column, then using Matrix4.translationValues(0.0, -2.6, 0.0) I gave the container, which contain the border, a nigative-padding(or similar) so it moved to the top of the indicatorColor.所以我给了一个 Column 给了 flexibleSpace,然后我可以把 TabBar 和容器放在那个列中,然后使用 Matrix4.translationValues(0.0, -2.6, 0.0) 我给了包含边框的容器,一个 nigative-padding (或类似的)所以它移到了 indicatorColor 的顶部。

return SafeArea(
  top: true,
  child: Scaffold(
    appBar: PreferredSize(
      preferredSize: Size.fromHeight(100.0),
      child: AppBar(
        backgroundColor: Theme.of(context).buttonColor,
        title: Text(
          'AppBar',
          textAlign: TextAlign.center,
          style: Theme.of(context).textTheme.title,
        ),
        centerTitle: true,
        elevation: 0.0,
        flexibleSpace: Padding(
          padding: const EdgeInsets.only(top: 50.0),
          child: Column(
            children: <Widget>[
              // Tab Bar
              new TabBar(
                indicatorColor: Theme.of(context).accentColor,
                tabs: <Tab>[
                  new Tab(
                    text: 'Tab1',
                  ),
                  new Tab(
                    text: 'Tab2',
                  ),
                ],
                controller: _tabController,
              ),
              // Border
              Container(
                // Negative padding
                transform: Matrix4.translationValues(0.0, -2.6, 0.0),
                // Add top border
                decoration: BoxDecoration(
                   border: Border(
                     top: BorderSide(
                        color: Color(0xFFc3c3c3),
                        width: 0.6,
                     ),
                   ),
                ),
              ),
            ],
          ),
        ),
      ),
    ),
    body: new TabBarView(
      children: <Widget>[
        new Tab1(),
        new Tab2(),
      ],
      controller: _tabController,
    ),
  ),
);

And the magic happened ^^奇迹发生了^^

带边框的 TabBar

Here's my version of spenster's solution ;这是我的spenster 解决方案版本;

Instead of a function, I created a new widget "BorderedTab" which implements Tab:我创建了一个实现 Tab 的新小部件“BorderedTab”,而不是一个函数:

import 'package:flutter/material.dart';

class BorderedTab extends StatelessWidget implements Tab {
  const BorderedTab({
    Key key,
    this.text,
    this.borderColor=Colors.grey,
    this.width=0.5,
  }) : super(key: key);

  final String text;
  final Color borderColor;
  final double width;

  @override
  Widget build(BuildContext context) {
    return Tab(
      child: Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Expanded(
                child: Container(
                    child: Center(
                        child: Text(text)
                    ),
                    decoration: BoxDecoration(
                        border: Border(
                            bottom: BorderSide(
                                width: width,
                                color: borderColor,
                            ),
                        ),
                    ),
                ),
            ),
          ]
      ),
    );
  }

  @override
  // TODO: implement child
  Widget get child => null;

  @override
  // TODO: implement icon
  Widget get icon => null;
}

then I used BorderedTab just like the regular Tab, but with:然后我像使用常规 Tab 一样使用 BorderedTab,但具有:

labelPadding: EdgeInsets.all(0.0), // Important to remove default padding

Final AppBar:最终应用栏:

import 'package:../widgets/bordered_tab.dart';

...

appBar: AppBar(
  backgroundColor: Theme.of(context).buttonColor,
  title: Text(
    'TabBar',
    textAlign: TextAlign.center,
    style: Theme.of(context).textTheme.title,
  ),
  centerTitle: true,
  elevation: 0.0,
  bottom: new TabBar(
    labelColor: Theme.of(context).primaryColor,
    indicatorColor:Theme.of(context).accentColor,
    labelPadding: EdgeInsets.all(0.0), // Important to remove default padding
    tabs: <Tab>[
      BorderedTab(
        text: 'Tab1',
        borderColor: Color(0xFFc3c3c3),
      ),
      BorderedTab(
        text: 'Tab2',
        borderColor: Color(0xFFc3c3),
      ),
    ],
    controller: _tabController,
  ),
),

Another approach is to use a stack and place the line underneath the tabs另一种方法是使用堆栈并将线放置在选项卡下方

               Stack(
                  alignment: Alignment.bottomCenter,
                  children: [
                    Container(
                      decoration: BoxDecoration(
                          border: Border(
                        bottom: BorderSide(color: Colors.white70, width: 1),
                      )),
                    ),
                    TabBar(
                      indicatorWeight: 3.0,
                      tabs: [
                        Tab(
                          icon: Icon(Icons.home),
                        ),
                        Tab(
                          icon: Icon(Icons.show_chart),
                        ),
                      ],
                    ),
                  ],
                ),

Simply you can wrap TabBar into DecoratedBox as below:简单地,您可以将TabBar包装到DecoratedBox 中,如下所示:

DecoratedBox(
    decoration: BoxDecoration(
    //This is for background color
    color: Colors.white.withOpacity(0.0),

    //This is for bottom border that is needed
    border: Border(
        bottom: BorderSide(color: AppColors.color4, width: 2.sp)),
    ),
    child: TabBar(
        ...
    ),
),

在此处输入图片说明

Hope you will get help.希望你能得到帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM