由于工作中项目需求,需要将h5转换为flutter代码。

其中的斑马纹背景需要根据接口返回的颜色来渲染,所以不能只是图片形式,无法通过decoration属性配置图片背景板。

楼主这边想到的方法就是通过 实现一个canvas绘制斑马纹类。使用stack布局,将斑马纹放在下方作为背景板,需要展示的内容在上方。实现 “斑马纹”背景(需要变换颜色)

文章主要分为 效果图、实现思维、代码、计算过程解释。希望对大家有所帮助

最终效果图

实现思维

斑马纹(45°角,向左倾斜)

使用custompaint(size: size(width, height), painter: 画笔)

custompaint(
   size: size(widget.width, widget.height),
   painter: 画笔,
)

画笔

继承 custompainter类,实现paint(canvas canvas, size size)方法,根据 宽度、高度、画笔宽度、间距 计算出各个点位。使用canvas. drawline方法 绘制出斑马纹。

@override
void paint(canvas canvas, size size) {
  …
  canvas. drawline();
}

斑马纹坐标位置计算

2.82 = 2倍根号2

1.41 = 根号二

  • 填充个数= 最大高度 / (画笔宽度1.41+间距) 向上取整。(从0, 0开始,左侧会露出空位,所以需要填充)
  • 条纹个数 = 宽度/(画笔宽度1.41+间距) 向上取整。
  • (x轴y轴) 偏移量 =画笔宽度 / 2.82 (画笔起始点、结束点会露出一小节,需要计算x,y偏移量。将左上角x,y减去偏移量,右下角x,y加上偏移量,补充此部分)
  • 起点坐标 =((画笔宽度1.41+间距) * 条纹index – 偏移量,– 偏移量)
  • 终点坐标 =((画笔宽度1.41+间距) * 条纹index – 偏移量+高度, 高度+偏移量)

圆角裁剪(如果需要)

由于画笔绘制的是直角的,所以作为背景板会超出,需要裁剪掉四个角。使用

cliprrect(
   borderradius: borderradius.all(radius.circular(10)),
   child: xxx
)

作为背景

使用stack布局,实现斑马纹在下方作为背景板,需要展示的内容在上方

stack(
  children: [
  	buildzebraback(…), 
  	需要展示的内容
  ]
)

代码

使用处 main_page.dart

stack(
  children: [
    positioned(
      child: zebrastripesback(
          width: 335,
          height: 44,
          linewidth: 10,
          spacing: 10,
          borderraduis: 10,
          linecolor: colors.blue),
      top: 0,
      left: 0,
    ),
    container(
      width: 335,
      height: 44,
      alignment: alignment.center,
      padding: edgeinsets.only(
          top: 10,
          left: 12,
          bottom: 10,
          right: 12),
      child: text(
              "英语",
              style: textstyle(
                color: color(0xffffffff),
                fontsize: 14.sp,
                fontweight: fontweight.w500),
            )
      )
  ]
)

斑马纹具体实现类 zebra_stripes_back.dart

import 'dart:math';
import 'package:flutter/material.dart';

// 斑马纹具体实现类
class zebrastripesback extends statefulwidget {
  zebrastripesback({
    this.width: 0,
    this.height: 0,
    this.spacing: 4,
    this.linewidth: 4,
    this.linecolor: colors.transparent,
    this.borderraduis: 0,
  });

  final double width; // 容器宽度
  final double height; // 容器高度 
  final double linewidth; // 斑马纹宽度
  final double spacing; // 间距
  final double borderraduis; // 容器圆角
  final color linecolor; // 斑马纹颜色

  @override
  state<statefulwidget> createstate() => _zebrastripesbackstate();
}

class _zebrastripesbackstate extends state<zebrastripesback> {
  @override
  void initstate() {
    super.initstate();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  widget build(buildcontext context) {
    return cliprrect(
        borderradius: borderradius.all(radius.circular(widget.borderraduis)),
        child: custompaint(
          size: size(widget.width, widget.height),
          painter: _zebrastripesbackpainter(
            maxwidth: widget.width,
            maxheight: widget.height,
            spacing: widget.spacing,
            linewidth: widget.linewidth,
            linecolor: widget.linecolor,
            borderraduis: widget.borderraduis,
          ),
        ));
  }
}

class _zebrastripesbackpainter extends custompainter {
  _zebrastripesbackpainter({
    this.maxwidth: 0,
    this.maxheight: 0,
    this.spacing: 4,
    this.linewidth: 4,
    this.linecolor: colors.black12,
    this.borderraduis: 0,
  });

  final double maxwidth;
  final double maxheight;
  final double spacing;
  final double linewidth;
  final color linecolor;
  final double borderraduis;

  @override
  void paint(canvas canvas, size size) {

    var paint = paint()
      ..isantialias = true
      ..style = paintingstyle.fill
      ..color = linecolor
      ..strokewidth = linewidth;

    int number = 0; // 个数
    int fillnumber = 0; // 填充个数
    double lineandspace = linewidth *1.41 + spacing; // 单个条纹宽 + 间距宽
    if (linewidth > 0) {
      number = (maxwidth / lineandspace).ceil();
      fillnumber = (maxheight / lineandspace).ceil(); // 填充个数
    }

    double deviation = linewidth / 2.82; // x y轴偏移量 = width / 2倍根号2
    for (int i = -fillnumber; i < number; i++) {
      var left = lineandspace * i - deviation;
      double dx = left;
      double dy = -deviation;
      double dx1 = left + maxheight;
      double dy1 = maxheight + deviation;
      canvas.drawline(
        offset(dx, dy),
        offset(dx1, dy1),
        paint,
      );
    }
  }

  @override
  bool shouldrepaint(custompainter olddelegate) => true;
}

计算过程解释

偏移量计算过程

填充个数计算过程

为什么画笔宽度需要乘 根号二?

缺少-填充

缺少-偏移量

以上就是android flutter实现”斑马纹”背景的示例代码的详细内容,更多关于flutte斑马纹背景的资料请关注其它相关文章!