需求:想要使用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的前景和背景实现,前景是边框,背景是填充。