flutter实现类似优惠券样式

1,795 阅读1分钟

先看图示:

效果图
其实要实现的就是左右两边的半圆跟虚线,flutter本身是没有提供像css那样的border style为dash直接实现,所以只能取巧实现,具体实现下面给出的代码参考了网上的写法:

绘制虚线

这里抽离出单独可配置widget组件:

import 'package:flutter/material.dart';

class DashLine extends StatelessWidget {
  final double height;
  final Color color;
  final double totalWidth;

  const DashLine({this.height = 1, this.color = Colors.black, this.totalWidth});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        final boxWidth = totalWidth??constraints.constrainWidth();
        final dashWidth = 5.0;
        final dashHeight = height;
        final dashCount = (boxWidth / (2 * dashWidth)).floor();
        return Flex(
          children: List.generate(dashCount, (_) {
            return SizedBox(
              width: dashWidth,
              height: dashHeight,
              child: DecoratedBox(
                decoration: BoxDecoration(color: color),
              ),
            );
          }),
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          direction: Axis.horizontal,
        );
      },
    );
  }
}

绘制左右两个半圆

其实就是绘制两个圆,背景色设置跟页面底色一样,然后将其定位出盒子自身的一半

画圆

Widget get CardCircle {
  return Container(
    width: 18,
    height: 18,
    decoration: BoxDecoration(
      shape: BoxShape.circle,
      color: AppColors.bg_gray, // 所有的颜色抽离到单独一个颜色文件方便管理
    ),
  );
}

完整具体实现

        // 这里要用sizebox而非container
        SizedBox(
            height: 18,
            child: Stack(
              alignment: Alignment.center,
              children: <Widget>[
                Padding(
                  child: const DashLine(color: AppColors.text_gray9,),
                  padding: EdgeInsets.symmetric(horizontal: 20),
                ),
                Positioned(
                  left: -9,
                  child: CardCircle,
                ),
                Positioned(
                  right: -9,
                  child: CardCircle,
                ),
              ],
            ),
          ),