一步一步搭建Flutter开发架子-Tabbar

1,247 阅读2分钟

一点点搭建一个架构,架构对于开发比较重要,有固定的模式,第一不容易产生bug,并且有利于对于项目以及开发架构的理解。 对于一个app,常见的架构一般是底部有Tabbar形式,或者采用抽屉的形式,底部Tabbar大部分app都是平铺的,中间有一块凸出来的形式。

普通Tabbar

比较简单代码直接贴出来了

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: normalBottomBar(),
    );
  }
  normalBottomBar() {
    return BottomNavigationBar(
      // 底部导航
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
            activeIcon: Icon(Icons.access_alarm)),
        BottomNavigationBarItem(icon: Icon(Icons.search), label: 'search'),
        BottomNavigationBarItem(icon: Icon(Icons.people), label: 'mine'),
      ],
      currentIndex: _selectedIndex,
      fixedColor: Colors.blue,
      elevation: 10, // default: 8.0
      type: BottomNavigationBarType.fixed,
      iconSize: 30,
      selectedFontSize: 12, // 默认是14,未选择是14
      onTap: _onItemTapped,
    );
  }
  _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

中间凸出的Tabbar

官方的Material风格库中存在这种效果,不过个人感觉跟现在流行的风格有点不太匹配,所以封装了一个接近于现在流行风格的Tabbar。 刚开始的效果是这样的: 凸出的按钮封装了一下的代码片段:

import 'dart:math';

import 'package:flutter/material.dart';

class CenterNavigationItem extends StatefulWidget {
  CenterNavigationItem({Key key, this.onTap}) : super(key: key);

  final Function onTap;

  @override
  _CenterNavigationItemState createState() => _CenterNavigationItemState();
}

class _CenterNavigationItemState extends State<CenterNavigationItem> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        // CustomPaint(size: Size(76, 76), painter: MyPainter()),
        Container(
          width: 76,
          height: 76,
          padding: EdgeInsets.all(8),
          decoration: BoxDecoration(
              color: Color.fromRGBO(250, 250, 250, 1),
              borderRadius: BorderRadius.circular(38)),
          child: FloatingActionButton(
              child: Icon(Icons.add),
              // child: TextField(),
              tooltip: '测试', // 长按弹出提示
              onPressed: () {
                widget.onTap();
              }),
        ),
      ],
    );
  }
}
// 主页面引用:
@override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: CenterNavigationItem(
        onTap: () {
          setState(() {
            _selectedIndex = 1;
          });
        },
      ),
      bottomNavigationBar: normalBottomBar(),
    );
  }

感觉还是差点意思, 在于底部线与线直接连接的不够平滑

带有动画效果的Tabbar

继续改造一下的想法就是通过CustomPainter去画一个半圆。效果如下: 代码片段:

class MyPainter extends CustomPainter {
  @override
  paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..isAntiAlias = false
      ..color = Colors.green
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 0
      ..style = PaintingStyle.stroke;
    print(pi);
    canvas.drawArc(
        new Rect.fromCircle(center: Offset(38, 38), radius: size.width / 2),
        pi,
        2 * pi * 0.5,
        false,
        paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

在凸出的按钮封装的代码中添加:

class _CenterNavigationItemState extends State<CenterNavigationItem> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        CustomPaint(size: Size(76, 76), painter: MyPainter()),
        class _CenterNavigationItemState extends State<CenterNavigationItem> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        // 这个位置加入!!!!!!!!!!
        CustomPaint(size: Size(76, 76), painter: MyPainter()),
        Container(
          width: 76,
          height: 76,
          padding: EdgeInsets.all(8),
          decoration: BoxDecoration(
              color: Color.fromRGBO(250, 250, 250, 1),
              borderRadius: BorderRadius.circular(38)),
          child: FloatingActionButton(
              child: Icon(Icons.add),
              // child: TextField(),
              tooltip: '测试', // 长按弹出提示
              onPressed: () {
                widget.onTap();
              }),
        ),
      ],
    );
  }
}
      ],
    );
  }
}

最终就是这个效果。还有就是也不能闭门造车,上网搜搜大家都是怎么去构建Tabbar的。其中在github上发现一个加入了动画的开源代码。Motion-Tab-Bar。分析了一波代码,看了一眼效果如下:

稍加修改了一下,留着以后项目可能用的上。over~欢迎讨论

one more thing...

  • 1, 路由管理,
  • 2, 国际化管理,
  • 3, 数据持久化管理,
  • 4, 响应式管理方法