如何使用Flutter實(shí)現(xiàn)手寫(xiě)簽名效果
思路
- 需要監(jiān)聽(tīng)用戶觸摸的起始點(diǎn)和結(jié)束點(diǎn),并記錄途經(jīng)點(diǎn),這里我使用了
StreamController - 將途經(jīng)點(diǎn)從起始位置到結(jié)束位置繪制出來(lái),這里用到
CustomPainter
繪制流程
- 獲取觸摸點(diǎn)作為畫(huà)筆的起始點(diǎn)
- 手機(jī)途經(jīng)點(diǎn)
- 繪制途徑路線
- 結(jié)束觸摸點(diǎn)重置畫(huà)筆
具體實(shí)現(xiàn)
需要一個(gè)Listener用來(lái)監(jiān)聽(tīng)用戶行為,并將這些行為的點(diǎn)添加到StreamController中, 兩個(gè)變量
final List _points = []; //承載對(duì)應(yīng)的點(diǎn)
final StreamController _controller = StreamController(); //數(shù)據(jù)通信
Widget _buildWriteWidget() {
return Stack(
children: [
Listener( //用來(lái)監(jiān)聽(tīng)用戶的觸摸行為
child: Container(
color: Colors.transparent,
),
onPointerDown: (PointerDownEvent event) {
_points.add(event.localPosition);
_controller.sink.add([_points]); //起始點(diǎn)的記錄
},
onPointerMove: (PointerMoveEvent event) {
_points.add(event.localPosition);
_controller.sink.add([_points]); //添加途經(jīng)點(diǎn)
},
onPointerUp: (PointerUpEvent event) {
_points.add(Offset.zero); //結(jié)束的標(biāo)記
},
),
StreamBuilder(
stream: _controller.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.hasData
? CustomPaint(painter: LinePainter(snapshot.data)) //關(guān)聯(lián)數(shù)據(jù)到Painter
: const SizedBox();
}),
Positioned(
bottom: 50,
right: 50,
child: FloatingActionButton(
onPressed: () {
_clear();
},
child: const Icon(Icons.cleaning_services),
))
],
);
}清除StreamController的內(nèi)容,重置數(shù)據(jù)
void _clear() {
_points.clear();
_controller.add(null);
}dispose時(shí)釋放StreamController
@override
void dispose() {
_controller.close();
super.dispose();
}
畫(huà)筆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); //繪制相應(yīng)的點(diǎn)
}
}
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}總結(jié)
到此這篇關(guān)于如何使用Flutter實(shí)現(xiàn)手寫(xiě)簽名效果的文章就介紹到這了,更多相關(guān)Flutter手寫(xiě)簽名效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android精靈動(dòng)畫(huà)用法實(shí)例
這篇文章主要介紹了Android精靈動(dòng)畫(huà)用法,實(shí)例分析了Android動(dòng)畫(huà)的相關(guān)使用技巧,需要的朋友可以參考下2015-06-06
Android HorizontalScrollView滑動(dòng)與ViewPager切換案例詳解
這篇文章主要介紹了Android HorizontalScrollView滑動(dòng)與ViewPager切換案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
利用HorizontalScrollView實(shí)現(xiàn)滑動(dòng)頁(yè)面時(shí)的縮放效果
這篇文章主要為大家詳細(xì)介紹了利用HorizontalScrollView實(shí)現(xiàn)滑動(dòng)頁(yè)面時(shí)的縮放效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Android Studio導(dǎo)入項(xiàng)目非常慢的解決方法
這篇文章主要為大家詳細(xì)介紹了Android Studio導(dǎo)入項(xiàng)目非常慢的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android 無(wú)障礙全局懸浮窗實(shí)現(xiàn)示例
本文主要介紹了Android 無(wú)障礙全局懸浮窗實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Android 中FloatingActionButton(懸浮按鈕)實(shí)例詳解
這篇文章主要介紹了Android 中FloatingActionButton(懸浮按鈕)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android App中各種數(shù)據(jù)保存方式的使用實(shí)例總結(jié)
這篇文章主要介紹了Android App中各種數(shù)據(jù)保存方式的使用實(shí)例,列舉了SharedPreferences接口、機(jī)身空間存儲(chǔ)、SD卡存儲(chǔ)和SQLite數(shù)據(jù)庫(kù)四種方式的代碼例子,需要的朋友可以參考下2016-04-04
Android編程設(shè)計(jì)模式之中介者模式詳解
這篇文章主要介紹了Android編程設(shè)計(jì)模式之中介者模式,結(jié)合實(shí)例形式詳細(xì)分析了Android中介者模式的概念、原理、使用場(chǎng)景、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2017-12-12
flutter RotationTransition實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了flutter RotationTransition實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫(huà),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07

