Flutter手绘输入插件pencil_field的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter手绘输入插件 pencil_field 的使用

pencil_field 是一个用于在不同设备和平台上进行手写输入的 Flutter 插件。它适用于任何自由手绘输入,如签名或绘图。本文将详细介绍如何使用 pencil_field 插件,并提供完整的示例代码。

功能概述

PencilField / PencilFieldController

PencilField 是一个实际的小部件,用于捕获和存储自由手绘/铅笔输入。每个 PencilField 需要一个控制器 (PencilFieldController) 来连接小部件和存储输入的 PencilDrawing 对象。

PencilDrawing

PencilDrawing 存储了由 PencilField 捕获的实际内容。你可以以版本化的格式存储和检索这些数据,以便未来版本的 PencilField 可以加载旧数据。

如何使用

基本用法

创建一个 PencilField 小部件并将其嵌入到页面中:

PencilField(
  controller: widget.controller,
  pencilPaint: Paint()
    ..color = Colors.black
    ..strokeWidth = 2.0,
  onPencilDrawingChanged: widget.onPencilDrawingChanged,
  decoration: PencilDecoration(
    type: PencilDecorationType.chequered,
    backgroundColor: Colors.white,
    patternColor: Colors.grey[300]!,
    numberOfLines: 10,
    strokeWidth: 2,
    padding: const EdgeInsets.all(10),
  ),
  pencilOnly: true,
)

显示输入结果也很简单,因为所有内容都以矢量格式存储,缩放(例如,创建预览)很容易:

PencilDisplay(
  pencilDrawing: widget.controller.drawing.scale(
    scale: scale,
  ),
  decoration: PencilDecoration(backgroundColor: Colors.white),
)

完整示例

以下是一个完整的示例,展示了如何使用 PencilField 及其相关的小部件 PencilDisplay,以及如何定义画笔、擦除、撤销和清除等交互功能。

import 'package:flutter/material.dart';
import 'package:pencil_field/pencil_field.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pencil Field Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Pencil Field Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final pencilController = PencilFieldController();
  double scale = 1;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Spacer(),
            _ScalingPencilDisplay(controller: pencilController),
            const SizedBox(height: 100),
            PencilFieldWithTools(
              controller: pencilController,
              onPencilDrawingChanged: _drawingChanged,
            ),
            const SizedBox(height: 100),
          ],
        ),
      ),
    );
  }

  void _drawingChanged(PencilDrawing _) {
    setState(() {});
  }
}

class _ScalingPencilDisplay extends StatefulWidget {
  final PencilFieldController controller;

  const _ScalingPencilDisplay({required this.controller});

  [@override](/user/override)
  State<_ScalingPencilDisplay> createState() => _ScalingPencilDisplayState();
}

class _ScalingPencilDisplayState extends State<_ScalingPencilDisplay> {
  double scale = 1.0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(8.0),
      padding: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black38),
        borderRadius: const BorderRadius.all(Radius.circular(8.0)),
        color: Colors.grey[200],
      ),
      child: Column(
        children: [
          const Text('Scaled drawing'),
          Slider(
            min: 0.25,
            max: 4,
            value: scale,
            onChanged: (value) {
              setState(() {
                scale = value;
              });
            },
          ),
          SizedBox(
            width: double.infinity,
            height: 200,
            child: PencilDisplay(
              pencilDrawing: widget.controller.drawing.scale(scale: scale),
              decoration: PencilDecoration(backgroundColor: Colors.white),
            ),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter手绘输入插件pencil_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter手绘输入插件pencil_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用pencil_field插件来实现手绘输入的示例代码。这个插件允许用户在屏幕上自由绘制图形,非常适合用于签名、绘图等应用场景。

首先,确保你已经在pubspec.yaml文件中添加了pencil_field依赖:

dependencies:
  flutter:
    sdk: flutter
  pencil_field: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,我们创建一个简单的Flutter应用,演示如何使用pencil_field插件。

main.dart

import 'package:flutter/material.dart';
import 'package:pencil_field/pencil_field.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pencil Field Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Pencil Field Demo'),
        ),
        body: Center(
          child: PencilFieldDemo(),
        ),
      ),
    );
  }
}

class PencilFieldDemo extends StatefulWidget {
  @override
  _PencilFieldDemoState createState() => _PencilFieldDemoState();
}

class _PencilFieldDemoState extends State<PencilFieldDemo> {
  final PencilFieldController _controller = PencilFieldController();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'Draw something here:',
            style: TextStyle(fontSize: 20),
          ),
          SizedBox(height: 20),
          Expanded(
            child: PencilField(
              controller: _controller,
              penColor: Colors.black,
              penStrokeWidth: 5.0,
              backgroundColor: Colors.white,
              onClear: () {
                // 当清除按钮被点击时触发
                _controller.clear();
              },
              onSave: (List<Offset> points) {
                // 当保存按钮被点击时触发,points包含所有绘制的点
                print('Saved points: $points');
                // 你可以在这里将点数据保存到数据库或进行其他处理
              },
            ),
          ),
          SizedBox(height: 20),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  _controller.clear();
                },
                child: Text('Clear'),
              ),
              SizedBox(width: 20),
              ElevatedButton(
                onPressed: () {
                  _controller.savePoints().then((points) {
                    // 处理保存的点数据
                  });
                },
                child: Text('Save'),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

说明

  1. 依赖添加:确保在pubspec.yaml中添加了pencil_field依赖。
  2. 控制器:使用PencilFieldController来控制手绘输入的行为。
  3. PencilField组件
    • controller:绑定到控制器。
    • penColor:设置画笔颜色。
    • penStrokeWidth:设置画笔粗细。
    • backgroundColor:设置背景颜色。
    • onClear:当清除按钮被点击时调用的回调。
    • onSave:当保存按钮被点击时调用的回调,返回绘制的点数据。
  4. 按钮:添加了两个按钮,一个用于清除画布,一个用于保存绘制的点数据。

这个示例代码展示了如何在Flutter中使用pencil_field插件来实现手绘输入功能。你可以根据需要进一步自定义和扩展这个示例。

回到顶部