如何使用Flutter實現手寫簽名效果

思路

  • 需要監聽用戶觸摸的起始點和結束點,並記錄途經點,這裡我使用瞭StreamController
  • 將途經點從起始位置到結束位置繪制出來,這裡用到CustomPainter

繪制流程

  • 獲取觸摸點作為畫筆的起始點
  • 手機途經點
  • 繪制途徑路線
  • 結束觸摸點重置畫筆

具體實現

需要一個Listener用來監聽用戶行為,並將這些行為的點添加到StreamController中, 兩個變量

final List _points = []; //承載對應的點
final StreamController _controller = StreamController(); //數據通信

Widget _buildWriteWidget() {
  return Stack(
    children: [
      Listener( //用來監聽用戶的觸摸行為
        child: Container(
          color: Colors.transparent,
        ),
        onPointerDown: (PointerDownEvent event) {
          _points.add(event.localPosition);
          _controller.sink.add([_points]);  //起始點的記錄
        },
        onPointerMove: (PointerMoveEvent event) {
          _points.add(event.localPosition);
          _controller.sink.add([_points]);  //添加途經點
        },
        onPointerUp: (PointerUpEvent event) {
          _points.add(Offset.zero); //結束的標記
        },
      ),
      StreamBuilder(
          stream: _controller.stream,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            return snapshot.hasData
                ? CustomPaint(painter: LinePainter(snapshot.data))  //關聯數據到Painter
                : const SizedBox();
          }),
      Positioned(
          bottom: 50,
          right: 50,
          child: FloatingActionButton(
            onPressed: () {
              _clear();
            },
            child: const Icon(Icons.cleaning_services),
          ))
    ],
  );
}

清除StreamController的內容,重置數據

void _clear() {
  _points.clear();
  _controller.add(null);
}

dispose時釋放StreamController

@override
void dispose() {
  _controller.close();
  super.dispose();
}

畫筆Painter

class LinePainter extends CustomPainter {
  final List<List<Offset>> lines;
  final Color paintColor = Colors.black;
  final Paint _paint = Paint();

  LinePainter(this.lines);

  @override
  void paint(Canvas canvas, Size size) {
    _paint.strokeCap = StrokeCap.round;
    _paint.strokeWidth = 5.0;
    if (lines.isEmpty) {
      canvas.drawPoints(PointMode.polygon, [Offset.zero, Offset.zero], _paint);
    } else {
      for (int i = 0; i < lines.length; i++) {
        for (int j = 0; j < lines[i].length - 1; j++) {
          if (lines[i][j] != Offset.zero && lines[i][j + 1] != Offset.zero) {
            canvas.drawLine(lines[i][j], lines[i][j + 1], _paint);  //繪制相應的點
          }
        }
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

總結

到此這篇關於如何使用Flutter實現手寫簽名效果的文章就介紹到這瞭,更多相關Flutter手寫簽名效果內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: