畫個簡單的 ConvexBottomBar


在〈底部工具列 BottomAppBar〉中談過,如果知道怎麼繪圖的話,可以做出按鈕處凸起的效果,若只是要示範個概念,底下是個簡單的範例:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Openhome.cc')),
        body: Center(
          child: Image(
            image: NetworkImage('https://openhome.cc/Gossip/images/caterpillar.jpg'),
            width: 200,
            height: 200,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        bottomNavigationBar: ConstrainedBox(
          constraints: BoxConstraints.tightFor(height: kBottomNavigationBarHeight),
          child: CustomPaint(
              size: Size.infinite,
              painter: ConvexBar(),
          ),
        )
      ),
    );
  }
}

class ConvexBar extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.blue;

    var halfWidth = size.width / 2;
    var halfHeight = size.height / 2;

    canvas.drawRect(
        Rect.fromCenter(
            center: Offset(halfWidth, halfHeight + kBottomNavigationBarHeight / 8),
            width: size.width,
            height: kBottomNavigationBarHeight),
        paint
    );
    canvas.drawCircle(
        Offset(halfWidth, halfHeight / 6),
        45,
        paint
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

簡單來說,ConvexBar 就是依尺寸與適當位置,畫個四邊形與圓形,執行後的效果如下:

畫個簡單的 ConvexBottomBar

CustomPaint 有個 child 特性,可以接受一個 WidgetCustomPainter 畫的圖不會覆蓋 child,因此若不想搭配 floatingActionButton,也可以自己做個簡單的

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(title: Text('Openhome.cc')),
          body: Center(
            child: Image(
              image: NetworkImage('https://openhome.cc/Gossip/images/caterpillar.jpg'),
              width: 200,
              height: 200,
            ),
          ),
          bottomNavigationBar: ConvexBottomBar()
      ),
    );
  }
}

class ConvexBottomBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: BoxConstraints.tightFor(height: kBottomNavigationBarHeight * 1.5),
      child: CustomPaint(
          size: Size.infinite,
          painter: ConvexBar(),
          child: IconButton(
            icon: Icon(Icons.pets,
              color: Colors.white,
            ),
          )
      ),
    );
  }
}

class ConvexBar extends CustomPainter {
  同上...略
}

這個範例是個簡單的示範,如何令其通用就自己試著依需求來重構了,執行後的效果如下:

畫個簡單的 ConvexBottomBar