Android?Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼
由于工作中項(xiàng)目需求,需要將H5轉(zhuǎn)換為Flutter代碼。
其中的斑馬紋背景需要根據(jù)接口返回的顏色來(lái)渲染,所以不能只是圖片形式,無(wú)法通過(guò)decoration屬性配置圖片背景板。
樓主這邊想到的方法就是通過(guò) 實(shí)現(xiàn)一個(gè)canvas繪制斑馬紋類(lèi)。使用Stack布局,將斑馬紋放在下方作為背景板,需要展示的內(nèi)容在上方。實(shí)現(xiàn) “斑馬紋”背景(需要變換顏色)
文章主要分為 效果圖、實(shí)現(xiàn)思維、代碼、計(jì)算過(guò)程解釋。希望對(duì)大家有所幫助
最終效果圖
實(shí)現(xiàn)思維
斑馬紋(45°角,向左傾斜)
使用CustomPaint(size: Size(width, height), painter: 畫(huà)筆)
CustomPaint( size: Size(widget.width, widget.height), painter: 畫(huà)筆, )
畫(huà)筆
繼承 CustomPainter類(lèi),實(shí)現(xiàn)paint(Canvas canvas, Size size)方法,根據(jù) 寬度、高度、畫(huà)筆寬度、間距 計(jì)算出各個(gè)點(diǎn)位。使用canvas. drawLine方法 繪制出斑馬紋。
@override void paint(Canvas canvas, Size size) { … canvas. drawLine(); }
斑馬紋坐標(biāo)位置計(jì)算
2.82 = 2倍根號(hào)2
1.41 = 根號(hào)二
- 填充個(gè)數(shù)= 最大高度 / (畫(huà)筆寬度1.41+間距) 向上取整。(從0, 0開(kāi)始,左側(cè)會(huì)露出空位,所以需要填充)
- 條紋個(gè)數(shù) = 寬度/(畫(huà)筆寬度1.41+間距) 向上取整。
- (x軸y軸) 偏移量 =畫(huà)筆寬度 / 2.82 (畫(huà)筆起始點(diǎn)、結(jié)束點(diǎn)會(huì)露出一小節(jié),需要計(jì)算x,y偏移量。將左上角x,y減去偏移量,右下角x,y加上偏移量,補(bǔ)充此部分)
- 起點(diǎn)坐標(biāo) =((畫(huà)筆寬度1.41+間距) * 條紋index – 偏移量,– 偏移量)
- 終點(diǎn)坐標(biāo) =((畫(huà)筆寬度1.41+間距) * 條紋index - 偏移量+高度, 高度+偏移量)
圓角裁剪(如果需要)
由于畫(huà)筆繪制的是直角的,所以作為背景板會(huì)超出,需要裁剪掉四個(gè)角。使用
ClipRRect( borderRadius: BorderRadius.all(Radius.circular(10)), child: xxx )
作為背景
使用Stack布局,實(shí)現(xiàn)斑馬紋在下方作為背景板,需要展示的內(nèi)容在上方
Stack( children: [ buildZebraBack(…), 需要展示的內(nèi)容 ] )
代碼
使用處 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( "英語(yǔ)", style: TextStyle( color: Color(0xFFFFFFFF), fontSize: 14.sp, fontWeight: FontWeight.w500), ) ) ] )
斑馬紋具體實(shí)現(xiàn)類(lèi) zebra_stripes_back.dart
import 'dart:math'; import 'package:flutter/material.dart'; // 斑馬紋具體實(shí)現(xiàn)類(lèi) 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; // 個(gè)數(shù) int fillNumber = 0; // 填充個(gè)數(shù) double lineAndSpace = lineWidth *1.41 + spacing; // 單個(gè)條紋寬 + 間距寬 if (lineWidth > 0) { number = (maxWidth / lineAndSpace).ceil(); fillNumber = (maxHeight / lineAndSpace).ceil(); // 填充個(gè)數(shù) } double deviation = lineWidth / 2.82; // x y軸偏移量 = width / 2倍根號(hào)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; }
計(jì)算過(guò)程解釋
偏移量計(jì)算過(guò)程
填充個(gè)數(shù)計(jì)算過(guò)程
為什么畫(huà)筆寬度需要乘 根號(hào)二?
缺少-填充
缺少-偏移量
以上就是Android Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Flutte斑馬紋背景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android?Flutter繪制有趣的?loading加載動(dòng)畫(huà)
- Android Flutter利用CustomPaint繪制基本圖形詳解
- Android Flutter制作交錯(cuò)動(dòng)畫(huà)的示例代碼
- Android Flutter表格組件Table的使用詳解
- Android Flutter實(shí)現(xiàn)GIF動(dòng)畫(huà)效果的方法詳解
- Android利用Flutter實(shí)現(xiàn)立體旋轉(zhuǎn)效果
- Android Flutter實(shí)現(xiàn)彈幕效果
- Android?Flutter實(shí)現(xiàn)有趣的頁(yè)面滾動(dòng)效果
- Android使用Flutter實(shí)現(xiàn)錄音插件
相關(guān)文章
手機(jī)/移動(dòng)前端開(kāi)發(fā)需要注意的20個(gè)要點(diǎn)
本文主要介紹了手機(jī)/移動(dòng)前端開(kāi)發(fā)需要注意的20個(gè)要點(diǎn),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03Android下拉列表選項(xiàng)框及指示箭頭動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了Android下拉列表選項(xiàng)框,及指示箭頭動(dòng)畫(huà)的制作代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Android自定義View實(shí)現(xiàn)心形圖案
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)心形圖案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Android用戶界面開(kāi)發(fā)之:TextView的使用實(shí)例
Android用戶界面開(kāi)發(fā)之:TextView的使用實(shí)例,需要的朋友可以參考一下2013-05-05android 控件同時(shí)監(jiān)聽(tīng)單擊和雙擊實(shí)例
這篇文章主要介紹了android 控件同時(shí)監(jiān)聽(tīng)單擊和雙擊實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08Android開(kāi)發(fā)之5.0activity跳轉(zhuǎn)時(shí)共享元素的使用方法
下面小編就為大家分享一篇Android開(kāi)發(fā)之5.0activity跳轉(zhuǎn)時(shí)共享元素的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01淺談Android應(yīng)用內(nèi)懸浮控件實(shí)踐方案總結(jié)
本篇文章主要介紹了淺談Android應(yīng)用內(nèi)懸浮控件實(shí)踐方案總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11activity 獲取rootView 設(shè)置backGroundColor的方法
下面小編就為大家?guī)?lái)一篇activity 獲取rootView 設(shè)置backGroundColor的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04