signature_page.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:lszlgl/base/base_lifecycle_state.dart';
  4. import 'package:signature/signature.dart';
  5. import 'package:lszlgl/widget/button.dart';
  6. class SignaturePageArgs {
  7. /// 签名数量
  8. int count;
  9. SignaturePageArgs({this.count = 1});
  10. @override
  11. String toString() {
  12. return {'count': count}.toString();
  13. }
  14. }
  15. /// 电子签名
  16. class SignaturePage extends StatefulWidget {
  17. final SignaturePageArgs args;
  18. const SignaturePage({
  19. super.key,
  20. required this.args,
  21. });
  22. @override
  23. State<SignaturePage> createState() => _SignaturePageState();
  24. }
  25. class _SignaturePageState extends BaseLifecycleState<SignaturePage> {
  26. late int count;
  27. late List<SignatureController> ctrlList;
  28. late PageController pageCtrl;
  29. final previousEnable = false.notifier<bool>();
  30. final nextEnable = false.notifier<bool>();
  31. final submitEnable = false.notifier<bool>();
  32. /// 清除当前签名
  33. void clearCurrent() {
  34. ctrlList[pageCtrl.page!.toInt()].clear();
  35. }
  36. /// 上一个
  37. void previousPage() {
  38. pageCtrl.jumpToPage(pageCtrl.page!.toInt() - 1);
  39. if (pageCtrl.page == 0) {
  40. previousEnable.value = false;
  41. }
  42. nextEnable.value = true;
  43. submitEnable.value = false;
  44. }
  45. /// 下一个
  46. void nextPage() {
  47. if (!checkCurrentPage()) return;
  48. pageCtrl.jumpToPage(pageCtrl.page!.toInt() + 1);
  49. if (pageCtrl.page == count - 1) {
  50. nextEnable.value = false;
  51. submitEnable.value = true;
  52. }
  53. previousEnable.value = true;
  54. }
  55. void submit() async {
  56. if (!checkCurrentPage()) return;
  57. // 取出所有签名资源
  58. List<Uint8List?> images = [];
  59. for (var ctrl in ctrlList) {
  60. images.add(await ctrl.toPngBytes());
  61. }
  62. MyNavigator.pop(images);
  63. }
  64. bool checkCurrentPage() {
  65. if (ctrlList[pageCtrl.page!.toInt()].isEmpty) {
  66. MyNavigator.showToast('请先签名');
  67. return false;
  68. }
  69. return true;
  70. }
  71. @override
  72. void onInit() {
  73. // 强制横屏
  74. SystemChrome.setPreferredOrientations([
  75. DeviceOrientation.landscapeLeft,
  76. DeviceOrientation.landscapeRight,
  77. ]);
  78. // 创建签名列表
  79. count = widget.args.count;
  80. ctrlList = List.generate(
  81. count,
  82. (index) => SignatureController(
  83. penStrokeWidth: 6,
  84. penColor: Colors.black,
  85. strokeJoin: StrokeJoin.round,
  86. strokeCap: StrokeCap.round,
  87. ),
  88. ).toList();
  89. pageCtrl = PageController();
  90. if (count == 1) {
  91. submitEnable.value = true;
  92. } else {
  93. nextEnable.value = true;
  94. }
  95. }
  96. @override
  97. void onDestroy() {
  98. SystemChrome.setPreferredOrientations([
  99. DeviceOrientation.portraitUp,
  100. DeviceOrientation.portraitDown,
  101. ]);
  102. for (var ctrl in ctrlList) {
  103. ctrl.dispose();
  104. }
  105. }
  106. @override
  107. Widget build(BuildContext context) {
  108. return Scaffold(
  109. body: Stack(
  110. children: [
  111. SizedBox(width: double.infinity, child: Image.asset(imgHomeTopBg, fit: BoxFit.cover)),
  112. buildBody(),
  113. ],
  114. ),
  115. );
  116. }
  117. Widget buildBody() {
  118. return Column(
  119. children: [
  120. myAppBar(title: '电子签名', toolbarHeight: 32),
  121. Expanded(
  122. child: Container(
  123. decoration: const BoxDecoration(
  124. color: Colors.white,
  125. ),
  126. width: double.infinity,
  127. child: PageView.builder(
  128. controller: pageCtrl,
  129. physics: const NeverScrollableScrollPhysics(),
  130. itemBuilder: (_, index) => Signature(
  131. controller: ctrlList[index],
  132. backgroundColor: Colors.transparent,
  133. ),
  134. ),
  135. ),
  136. ),
  137. buildBottom(),
  138. ],
  139. );
  140. }
  141. Widget buildBottom() {
  142. EdgeInsets margin = EdgeInsets.only(left: 8, right: 8, top: 8, bottom: getBottomPadding(8));
  143. return Row(
  144. children: [
  145. Expanded(child: MyButton('清除重写', onTap: clearCurrent, margin: margin)),
  146. previousEnable.builder(
  147. (v) => v ? Expanded(child: MyButton('上一位', onTap: previousPage, margin: margin)) : const SizedBox.shrink()),
  148. nextEnable.builder(
  149. (v) => v ? Expanded(child: MyButton('下一位', onTap: nextPage, margin: margin)) : const SizedBox.shrink()),
  150. submitEnable.builder(
  151. (v) => v ? Expanded(child: MyButton('提交', onTap: submit, margin: margin)) : const SizedBox.shrink()),
  152. ],
  153. );
  154. }
  155. }