flutter canvas實現既有邊框又有填充的圖案
阿新 • • 發佈:2020-12-17
需求:想要使用canvas畫一個邊框和填充顏色不一樣的圖案,flutter和js不一樣,只有一個paint畫筆的style屬性可以設定,style值可以有兩種型別,一種的PaintingStyle.stoke,代表邊框還有一種是PaintingStyle.fill,代表填充,這兩種值只能取其一,那麼想要既有邊框又有顏色填充怎麼辦呢?
第一種解決方案:
思路:使用Stack最上一層畫只有邊框的圖形,下面一層畫填充的圖形,兩層的圖形區別只是一個style屬性值是邊框,並且設定邊框顏色和寬度,另一層style屬性值是填充,並且設定填充顏色,例子看上一篇文章: flutter canvas及實現氣泡
第二種解決方案:
使用save()、saveLayer() 和 restore()來繪製兩層,一層邊框,一層填充;
思路:save()方法儲存的是之前繪製的圖形, restore()方法是合併兩次的圖形,saveLayer()和save()差不多,和save()不一樣的是,兩次繪製在不一樣的圖層,saveLayer()有第一個引數Rect,第二次繪製的有效區域,超出無效,第二個引數是第二次繪製的畫筆。saveLayer()之後新建圖層。
例子:
1,使用save()
效果:
import 'package:flutter/cupertino.dart' ;
import 'package:flutter/material.dart';
class CanvasWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
// throw UnimplementedError();
return Center(
child: Container(
width: 100,
height: 100,
child: CustomPaint (
painter: MyPainter(),
),
),
);
}
}
class MyPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
canvas.drawRect(Rect.fromCircle(center: Offset(size.width/2.0, size.height/2.0),radius:50.0), Paint()..color=Colors.blueAccent..style=PaintingStyle.fill );
canvas.save();//表示儲存之前的畫的東西
canvas.drawRect(Rect.fromCircle(center: Offset(size.width/2.0, size.height/2.0),radius:50.0), Paint()..color=Colors.orange..style=PaintingStyle.stroke..strokeWidth=5 );
canvas.restore();//表示合併兩次畫的東西
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {//重build 的時候是否重繪
// TODO: implement shouldRepaint
return false;
throw UnimplementedError();
}
}
2,使用savaLayer()
效果:跟上面一樣,不過兩者的圖層不一樣
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CanvasWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
// throw UnimplementedError();
return Center(
child: Container(
width: 100,
height: 100,
child: CustomPaint(
painter: MyPainter(),
),
),
);
}
}
class MyPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
canvas.drawRect(Rect.fromCircle(center: Offset(size.width/2.0, size.height/2.0),radius:50.0), Paint()..color=Colors.blueAccent..style=PaintingStyle.fill );
// canvas.save();//表示儲存之前的畫的東西
Paint paint= Paint()..color=Colors.orange..style=PaintingStyle.stroke..strokeWidth=5;
canvas.saveLayer(Rect.fromCircle(center: Offset(size.width/2.0, size.height/2.0),radius:50.0),paint);
canvas.drawRect(Rect.fromCircle(center: Offset(size.width/2.0, size.height/2.0),radius:50.0), paint);
canvas.restore();//表示合併兩次畫的東西
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {//重build 的時候是否重繪
// TODO: implement shouldRepaint
return false;
throw UnimplementedError();
}
}
第三種方案:
猜想可以通過canvas的前景和背景實現,前景是邊框,背景是填充。