Flutter 实现“斑马纹”背景

由于工作中项目需求,需要将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;
}

计算过程解释

偏移量计算过程

填充个数计算过程

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

缺少-填充

缺少-偏移量

Flutter 实现“斑马纹”背景(需要变换颜色)的更多相关文章

  1. 计算机中的颜色XIV——快速变换颜色的V分量

    基本知识回顾: 计算机中的颜色Color,用RGB模式存储(用R.G.B三个分量表示颜色,每个分量的范围是0—255). 而计算机中的颜色除了用RGB模式表示以外,常见的还有HSV模式(或者是HSB. ...

  2. phpstorm调整背景、字体颜色

    从这个网站(http://phpstorm-themes.com/)下载各类主题的xml文件, 然后将文件放到phpStorm的文件夹中,比如:C:\Users\USERNAME\.PhpStorm2 ...

  3. HTML快速入门5——不规则表格、表格背景、边框颜色

    转自:http://blog.csdn.net/ysuncn/article/details/2214153 不规则表格 例子: <table border=1><tr>< ...

  4. 【JavaScript】轻易改变的背景和字体颜色页面

    JavaScript,点击button改变页面背景和字体颜色,网页有N颜色的变化button.点击不同button,网页字体和背景将被改变为不同的颜色. 非常easy的JavaScript小程序. 一 ...

  5. 设置LISTControl控件某一行的背景和文字颜色

    定义宏 用listcontrol的SetItemData设置某一行的属性,通过自定义属性标识实现. 自定义某行内容颜色属性: #define COLOR_DEFAULT 0 //默认颜色 #defin ...

  6. navigationItem.rightBarButtonItem 设置背景图片,颜色更改解决的方法

    self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@& ...

  7. Android中通过xml改变背景及文字颜色

    原创文章,转载请注明出处,谢谢! 本篇主要介绍Android开发中,通过XML资源文件来设置控件在不同状态下的背景及文字颜色.关于xml改变背景及文字颜色的原理,大家可以去看一下郭霖大神的源码分析文章 ...

  8. (转)Android 自定义 spinner (背景、字体颜色)

    Android 自定义 spinner (背景.字体颜色) (2012-07-04 17:04:44)   1.准备两张图片,并做好9.png   2.在drawable中定义spinner_sele ...

  9. 通过C语言程序改动控制台的背景和前景颜色

    本文主要解说怎样通过C语言来改动dos背景和前景颜色.我们首先来看一下dos的背景颜色的属性. 打开開始菜单,点击执行,弹出执行对话框.输入cmd,回车. (打开dos控制台) 在命令提示符界面下,输 ...

随机推荐

  1. 【面试普通人VS高手系列】Fail-safe机制与Fail-fast机制分别有什么作用

    前段时间一个小伙伴去面试,遇到这样一个问题. "Fail-safe机制与Fail-fast机制分别有什么作用" 他说他听到这个问题的时候,脑子里满脸问号.那么今天我们来看一下,关于 ...

  2. 超星尔雅看课刷题小tips

    用chrom浏览器,先安装扩展程序Tampermonkey BETA 然后进入> https://greasyfork.org/zh-CN 找一款适合自己的脚本安装即可刷课.

  3. Unity—2D边缘检测(描边效果)

    一.ShaderLab 1.Alpha值边缘检测 根据图片的Alpha值边缘判定,向内扩一段距离做边缘,颜色设置未描边颜色: 片元着色阶段,向上下左右四个方向做检测,有一个点的透明度为0,判定为边缘: ...

  4. npm 报错This is probably not a problem with npm. There is likely additional logging output above.

    报错This is probably not a problem with npm. There is likely additional logging output above. 安装了一个插件后 ...

  5. JavaScript基础第05天笔记

    JavaScript基础第05天笔记 1 - 作用域 1.1 作用域概述 通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域.作用域的使用提 ...

  6. 共读《redis设计与实现》-单机(一)

    上一章我们讲了 redis 基本类型的数据结构 和 对象系统 ,这篇来说一下单机redis 的知识点. 一.数据库 一个数据库在redis中就有一个结构体,而数据库的结构体是由redisServer这 ...

  7. python基础练习题(题目 斐波那契数列II)

    day16 --------------------------------------------------------------- 实例024:斐波那契数列II 题目 有一分数序列:2/1,3 ...

  8. [AcWIng 799] 最长连续不重复子序列

    点击查看代码 #include<iostream> using namespace std; const int N = 1e5 + 10; int a[N], s[N]; int mai ...

  9. 【mq】从零开始实现 mq-04-启动检测与实现优化

    前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...

  10. web渗透学习目录

    一,基础学习 01.基础学习 [[编码总结]] [[JSON三种数据解析方法]] [[js加密,解密]] [[Internet保留地址和非保留地址.内网和公网.VNC和UltraVN]] 代理 [[S ...