Flutter 浅析之 自定义view (自定义图形) 三

17 篇文章 0 订阅
12 篇文章 2 订阅

技术无止境,只怕不学习啊,Flutter 我们开始吧

绘制路径drawPath

drawPath(Path path, Paint paint)

绘制路径非常的简单,首先需要一个要绘制的路径path,然后就是这个paint了。
Path的用法也非常的简单,下面列出一下常用的方法:

方法名作用
moveTo将路径起始点移动到指定的位置
relativeMoveTo相对于当前位置移动到
lineTo从当前位置连接指定点
relativeLineTo相对当前位置连接到
arcTo二阶贝塞尔曲线
conicTo三阶贝塞尔曲线
add**添加其他图形,如addArc,在路径是添加圆弧
contains路径上是否包括某点
transfor 给路径做matrix4变换
combine结合两个路径
close关闭路径,连接路径的起始点
reset重置路径,恢复到默认状态

举个例子:

 @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Path path = new Path();
    path.lineTo(200, 300);
    canvas.drawPath(path, _paint);
  }

效果:
在这里插入图片描述

也可以绘制多个过程path

 @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Path path = new Path();

    path.moveTo(50, 50);
    path.lineTo(160, 50);
    path.lineTo(160, 160);
    path.lineTo(50, 160);

    path.moveTo(160, 105);
    path.lineTo(50, 105);

    path.moveTo(50, 50);
    path.lineTo(50, 160);

    canvas.drawPath(path, _paint);
  }

效果:
在这里插入图片描述
我们也可以尝试画画其他的图形
使用arcTo绘制曲线,不熟悉贝塞尔曲线的童鞋可以自行google你科普下。
二阶贝塞尔曲线绘制弧线

 @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Path path = new Path();
    path.arcTo(Rect.fromCircle(center: Offset(100, 100),radius: 80),0,3.14,false);
    canvas.drawPath(path, _paint);
  }

效果:
在这里插入图片描述

或者直接绘制一个圆

 @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Path path = new Path();
    path.arcTo(Rect.fromCircle(center: Offset(100, 100),radius: 80),0,6.28,false);
    canvas.drawPath(path, _paint);
  }

效果:
在这里插入图片描述
当然我们也可以使用三阶贝塞尔曲线来绘制其他的图形:

比如,我对你们的爱哦

@override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Path path = new Path();

    var width = 200;
    var height = 300;
    path.moveTo(width / 2, height / 4);
    path.cubicTo((width * 6) / 7, height / 9, (width * 12) / 13,
        (height * 2) / 5, width / 2, (height * 7) / 12);
    canvas.drawPath(path, _paint);

    Path path2 = new Path();
    path2.moveTo(width / 2, height / 4);
    path2.cubicTo(width / 7, height / 9, width / 13, (height * 2) / 5,
        width / 2, (height * 7) / 12);
    canvas.drawPath(path2, _paint);
  }

效果:

在这里插入图片描述
绘制图片drawImage

drawImage(Image image, Offset p, Paint paint)

绘制起来也非常的简单,首先我们需要获取本地图片文件,然后绘制图片即可。
注意:自定义绘制Image 使用的是ui.Image对象

import 'dart:ui';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterapptest/NewRoute.dart';
import 'TestPainter.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red, // 风格颜色
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      routes:{
        "new_page":(context) => NewRoute(),
      },
      home: MyHomePage(title: '测试项目'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ui.Image _image;

  @override
  void initState() {
    super.initState();

    /**
     * 注意在初始化函数里面加加载图片
     * build 函数中把图片传给TestPainter对象
     */
    load("images/timg.jpg").then((i) {
      setState(() {
        _image = i;
      });
    });
  }
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    var paint = CustomPaint(
        size: Size(300,300),
        painter: TestPainter(_image),
    );
    return Scaffold(
      appBar: AppBar(
        title: Text( "Canvas的用法"),
      ),
      body: Container(
        child: paint,
      ),
    );
  }
  
  /// 通过assets路径,获取资源图片
  Future<ui.Image> load(String asset) async {
    ByteData data = await rootBundle.load(asset);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    ui.FrameInfo fi = await codec.getNextFrame();
    return fi.image;
  }
  
}

自定义view类 TestPainter:

import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/material.dart';

class TestPainter extends CustomPainter {
  Paint _paint = new Paint()
    ..color = Colors.blueAccent // 画笔颜色
    ..strokeCap = StrokeCap.round //画笔笔触类型
    ..isAntiAlias = true //是否启动抗锯齿
    ..strokeWidth = 6.0 //画笔的宽度
    ..style = PaintingStyle.stroke; // 样式
  ui.Image _image;

  TestPainter(this._image) {
    this._image = _image;
  }

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
      if (_image != null) {
          print(_image);
          canvas.drawImage(_image, Offset(0, 0), _paint);
      }
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    ///是否需要重绘
    return false;
  }
}

效果:
在这里插入图片描述
改变图片的大小

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint

      if (_image != null) {
//          canvas.drawImage(_image, Offset(0, 0), _paint);
      canvas.drawImageRect(_image, Offset(0.0, 0.0) & Size(_image.width.toDouble(), _image.height.toDouble()), Offset(0.0, 0.0) & Size(200, 200), _paint);
      }
  }

效果:
在这里插入图片描述

绘制颜色drawColor

绘制颜色用起来就比较简单了,主要是用来给你绘制过的图形上做颜色的变换,颜色的变换模式有多种
先绘制一个颜色为蓝色的圆

 @override
  void paint(Canvas canvas, Size size) {
      canvas.drawCircle(Offset(100, 100), 80.0, _paint);
  }

效果:
在这里插入图片描述

绘制红色

canvas.drawColor(Colors.red, BlendMode.color);

效果:
在这里插入图片描述
或者我们修改绘制的模式为

 Paint _paint = new Paint()
    ..color = Colors.blueAccent // 画笔颜色
    ..strokeCap = StrokeCap.round //画笔笔触类型
    ..isAntiAlias = true //是否启动抗锯齿
    ..strokeWidth = 6.0 //画笔的宽度
    ..style = PaintingStyle.stroke // 样式
    ..blendMode = BlendMode.colorDodge; // 模式

效果:

在这里插入图片描述
其他的可以自行尝试 本篇文章就到这里了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值