dart 在Flutter中添加标签的底部边框

sycxhyv7  于 2023-06-19  发布在  Flutter
关注(0)|答案(9)|浏览(251)

我想做的是添加一个底部边界的tabBar,所以它将在标签标题和以上的indicatorColor和活动和非活动标签,就像所附的图像。

红线是我要添加的内容,绿色线是indicatorColor。

  • 注意,通常我使用'bottom'为appBar这样做,但这里bottom保留给TabBar*。

这可能吗?
多谢了

rqenqsqc

rqenqsqc1#

你可以像abdulrahmanAbdullah说的那样设置AppBar shape属性。但是如果你确实需要在指示器上方的边框,你可以把它放在每个标签栏项目的内部。这里有一个关于它的看法:

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),
            ],
          ),
        ),
      ),
    );
  }
}
wfypjpf4

wfypjpf42#

尝试设置appBar边框:

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

c2e8gylq3#

只需将TabBar Package 成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(
        ...
    ),
),

希望你能得到帮助。

pvcm50d1

pvcm50d14#

我设法做到这一点,使用'flexibleSpace'属性,而不是'底部'属性,因为flexibleSpace可以有任何部件,而不仅仅是'PreferredSizeWidget'像底部。
所以我给了flexibleSpace一个Column,然后我能够将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,
    ),
  ),
);

奇迹发生了

rqenqsqc

rqenqsqc5#

另一种方法是使用堆栈并将行放在制表符下面

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),
                        ),
                      ],
                    ),
                  ],
                ),
wydwbb8l

wydwbb8l6#

下面是我的spenster's solution版本;
我创建了一个新的小部件“BorderedTab”,而不是一个函数,它实现了Tab:

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;
}

然后我使用BorderedTab就像常规的Tab一样,但是:
labelPadding: EdgeInsets.all(0.0), // Important to remove default padding
最终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,
  ),
),
hfsqlsce

hfsqlsce7#

使用DecoratedBox和PreferredSize

首先将TabBar放入PreferredSize中:

child: AppBar(
      bottom: PreferredSize(
        preferredSize: Size.fromHeight(50),
        child: TabBar(
          tabs: [
            Tab(
              text: 'tab-1',
            ),
            Tab(
              text: 'tab-2',
            ),
            Tab(
              text: 'tab-3',
            ),
          ],
        ),
      ),
    ),

然后用DecoratedBox Package TabBar

child: AppBar(
      bottom: PreferredSize(
        preferredSize: Size.fromHeight(50),
        child: DecoratedBox(
          decoration: BoxDecoration(
            border: Border(bottom: BorderSide(width: 2,color: Color.fromARGB(255, 255, 0, 0)))
          ),
          child: TabBar(
            tabs: [
              Tab(
                text: 'tab-1',
              ),
              Tab(
                text: 'tab-2',
              ),
              Tab(
                text: 'tab-3',
              ),
            ],
          ),
        ),
      ),
    ),
prdp8dxp

prdp8dxp8#

不使用其他元素的最简单方法是使用BoxShadow和TabBar,如下所示:

TabBar(
                        controller: _tabController,
                        indicator: BoxDecoration(
                                                 boxShadow: [
                            BoxShadow(
                              color: Colors.red,                         
                              offset: Offset(0, 2.0),
                            )
                          ],
                        
                          color: Colors.white,
                        ),
                        labelColor: Colors.red,
                        unselectedLabelColor: Colors.grey.shade900,
                        labelPadding: EdgeInsets.symmetric(horizontal: 10.0),
                        isScrollable: false,
                        tabs: [
                          Tab(
                            text: 'T1',
                          ),
                          Tab(
                            text: 'T2',
                          ),
                          Tab(
                            text: 'T3',
                          ),
                          Tab(
                            text: 'T4',
                          ),
                        ],
                      ),

或者使用UnderlineTabIndicator作为TabBar的指示符参数:

indicator: UnderlineTabIndicator(
                  borderSide: BorderSide(width: 3.0),
                  insets: EdgeInsets.symmetric(horizontal: 30.0),
                ),
djmepvbi

djmepvbi9#

我想添加一个answer
所有的答案都有一个问题,由于这个问题,底线或者高于或者低于指示器,并且也很难控制它的高度。
好吧,这是Flutter3中的一个工作版本

PreferredSize(
                    preferredSize: Size.fromHeight(kToolbarHeight),
                    child: DecoratedBox(
                      decoration: BoxDecoration(
                        border: Border(
                          bottom: BorderSide(
                            color: AppColors.border,
                            width: 3,
                          ),
                        ),
                      ),
                      child: TabBar(
                        labelColor: AppColors.secondText,
                        unselectedLabelColor: AppColors.grayText,
                        indicator: UnderlineTabIndicator(
                          borderSide: BorderSide(
                              width: 3.0, color: AppColors.secondText),
                          insets: EdgeInsets.symmetric(horizontal: 30.0),
                        ),
                        tabs: [
                          Tab(
                            text: "Tab 1",
                          ),
                          Tab(
                            text: "Tab 2",
                          ),
                        ],
                      ),
                    ),
                  ),

相关问题