美文网首页flutterFlutter
Flutter 自定义特殊形状的tabbar

Flutter 自定义特殊形状的tabbar

作者: 木_穆 | 来源:发表于2019-09-28 09:21 被阅读0次
    先看效果! 自定义形状TabBar
    实现

    成员变量
    List<Widget> pages = List<Widget>();用来存放tabs分别对应的页面。
    tabbar作为内容的容器 CustomerNotification用来容器内部Widget来通知tabbar做出改变。

    NotificationListener的’ child‘是页面显示内容,NotificationListener用来监听CustomerNotification。

    看设计,TabBar是悬浮的设计,不能用官方库提供的TabBar。TabBar和后面的内容是堆叠的,所以用Stack widget。
    Stack: 取代线性布局,Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝对定位(absolute positioning )布局模型设计的。
    Positioned,用Positioned绝对定位悬浮的TabBar。 bottom: 15, left: 20, right: 20(top这里不需要设置)分别设计和容器的边距。

    Positioned的child就是你自己需要定制的tabbar形状。

    全部代码如下:

    /*
     * File: /Users/ottpay/Git/fyh_transfer/lib/Account/accountHomePage.dart
     * Created Date: 2019-09-27 4:13:15
     * Author: 木穆  pengxuan.li@ott.ca
     * Copyright (c) 2019 OTT Pay HK
     */
    
    
    
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:fyh_transfer/Send/sendHomePage.dart';
    import 'package:fyh_transfer/Order/orderHomePage.dart';
    import 'package:fyh_transfer/Account/accountHomePage.dart';
    
    class FYHTabbar extends StatefulWidget {
      @override
      FYHTabbarState createState() => FYHTabbarState();
    }
    
    class CustomerNotification extends Notification {
      CustomerNotification(this.enable);
      final bool enable;
    }
    
    class FYHTabbarState extends State<FYHTabbar>
         {
      List<Widget> pages = List<Widget>();
    
      bool sendeEnable = false;
      SendHomePage _sendHomePage = SendHomePage();
    
      int _activeIndex = 1; //激活项
      double _height = 48.0; //导航栏高度
      double _floatRadius = 30; //悬浮图标半径
    
      List _navs = [
        Icons.search,
        Icons.ondemand_video,
        Icons.music_video,
      ]; //导航项
    
      @override
      void initState() {
        super.initState();
        pages..add(OrderHomePage())..add(_sendHomePage)..add(AccountHomePage());
      }
    
      @override
      Widget build(BuildContext context) {
        double width = MediaQuery.of(context).size.width - 40;
        _floatRadius = _activeIndex == 1 ? 40 : 30;
        return NotificationListener<CustomerNotification>(
            onNotification: (notification) {
              setState(() {
                sendeEnable = notification.enable;
              });
            },
            child: Container(
              child: Stack(children: [
                pages[_activeIndex],//tabbar要存放的页面
                Positioned(//用Positioned绝对定位悬浮的TabBar
                  bottom: 15,
                  left: 20,
                  right: 20,
                  child: Container(
                    padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
                    width: width,
                    height: 58,
                    child: Stack(
                      overflow: Overflow.visible,
                      children: <Widget>[
                        //所有图标
                        DecoratedBox(
                          decoration: BoxDecoration(
                            color: Color(0xFFf2f4f5), // 底色
                            shape: BoxShape.rectangle, // 默认值也是矩形
                            borderRadius:
                                new BorderRadius.circular(_height / 2), // 圆角度
                            boxShadow: [
                              BoxShadow(
                                  color: Color(0xffc1c1c1),
                                  offset: Offset(2.0, 2.0),
                                  blurRadius: 50.0,
                                  spreadRadius: 2.0)
                            ],
                          ),
                          child: SizedBox(
                            height: _height,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceAround,
                              crossAxisAlignment: CrossAxisAlignment.center,
                              children: _navs
                                  .asMap()
                                  .map((i, v) => MapEntry(
                                      i,
                                      GestureDetector(
                                        child: Container(
                                          color: Color(0xFFf2f4f5),
                                          margin: EdgeInsets.all(0),
                                          child: Icon(v,
                                              color: _activeIndex == i
                                                  ? Colors.pink
                                                  : Colors.grey),
                                          width: width / 3 - 30,
                                          height: _height - 10,
                                        ),
                                        onTap: () {
                                          _switchNav(i);
                                        },
                                      )))
                                  .values
                                  .toList(),
                            ),
                          ),
                        ),
                        //浮动图标
                        Positioned(
                          bottom: 4,
                          left: (width) / 2 - _floatRadius,
                          child: DecoratedBox(
                            decoration:
                                ShapeDecoration(shape: CircleBorder(), shadows: [
                              BoxShadow(
                                  blurRadius: 2,
                                  offset: Offset(0, 2),
                                  spreadRadius: 0,
                                  color: _activeIndex == 1
                                      ? Colors.pink
                                      : Colors.grey),
                            ]),
                            child: GestureDetector(
                              child: CircleAvatar(
                                  radius: _floatRadius, //浮动图标和圆弧之间设置8pixel间隙
                                  backgroundColor: Color(0xfff2f4f5),
                                  child: Icon(_navs[1],
                                      color: sendeEnable && _activeIndex == 1
                                          ? Colors.pink
                                          : Colors.black38)),
                              onTap: () {
                                _clickMiddleBtn();
                              },
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                )
              ]),
            ));
        ;
      }
    
      //中间按钮
      _clickMiddleBtn() {
        if (_activeIndex == 1) {
          if (sendeEnable) {
            print('send');
          }
        } else {
          _switchNav(1);
        }
      }
    
      //切换导航
      _switchNav(int newIndex) {
        print(newIndex);
        double oldPosition = _activeIndex.toDouble();
        double newPosition = newIndex.toDouble();
        if (oldPosition != newPosition) {
          setState(() {
            _activeIndex = newIndex;
          });
        }
      }
    
      @override
      void dispose() {
        super.dispose();
      }
    }
    
    

    相关文章

      网友评论

        本文标题:Flutter 自定义特殊形状的tabbar

        本文链接:https://www.haomeiwen.com/subject/koyzuctx.html