1. 程式人生 > 其它 >flutter canvas實現既有邊框又有填充的圖案

flutter canvas實現既有邊框又有填充的圖案

技術標籤:canvasflutter

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