flutter_integrated_whb/lib/pages/mine/mine_sign_page.dart

365 lines
9.0 KiB
Dart
Raw Normal View History

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
class MineSignPage extends StatelessWidget {
const MineSignPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: const SignatureConfirmPage(),
);
}
}
class SignatureConfirmPage extends StatefulWidget {
const SignatureConfirmPage({super.key});
@override
State<SignatureConfirmPage> createState() => _SignatureConfirmPageState();
}
class _SignatureConfirmPageState extends State<SignatureConfirmPage> {
final GlobalKey _signatureKey = GlobalKey();
List<Offset?> _points = [];
bool _hasSignature = false;
File? fileN;
Uint8List? _postBytes;
late String imagepath="";
void _clearSignature() {
setState(() {
_points.clear();
_hasSignature = false;
});
}
void _confirmSignature() {
if (!_hasSignature) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('请先签名')),
);
return;
}
_saveSignPic();
// // 保存签名逻辑
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(content: Text('签名已确认')),
// );
//模拟保存后返回
}
// 保存签名
void _saveSignPic() async{
RenderRepaintBoundary boundary = _signatureKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
var image = await boundary.toImage(pixelRatio: 1);
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Directory dir = await getTemporaryDirectory();
String path = dir.path +"/"+ 'sign.png';
File file2 = File(path);
// 检查文件是否存在
if (await file2.exists()) {
// 文件存在,删除文件
await file2.delete();
}
var file = await File(path).create(recursive: true);
if(byteData != null){
file.writeAsBytesSync(byteData.buffer.asInt8List(),flush: true);
setState(() {
_postBytes = byteData.buffer.asUint8List();
fileN = file;
imagepath = file.path;
Future.delayed(const Duration(milliseconds: 500), () {
Navigator.pop(context,imagepath);
});
});
}
}
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
@override
void dispose() {
// 不要忘记重置方向设置,以避免影响其他页面或应用。
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
// 标题区域
_buildTitleBar(),
// MyAppbar(title: "签字"),
// 签字区域
Expanded(
child: _buildSignatureArea(),
),
// 按钮区域
_buildActionButtons(),
],
),
),
);
}
Widget _buildTitleBar() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context),
),
const Text(
'签字',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 48), // 占位保持标题居中
],
),
);
}
Widget _buildSignatureArea() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey[300]!),
),
child: Column(
children: [
// 签字画布
Expanded(
child: GestureDetector(
onPanStart: (details) {
setState(() {
_points.add(details.localPosition);
_hasSignature = true;
});
},
onPanUpdate: (details) {
setState(() {
_points.add(details.localPosition);
});
},
onPanEnd: (details) {
setState(() {
_points.add(null);
});
},
child: RepaintBoundary(
key: _signatureKey,
child: Stack(
children: [
// if (imagepath.length > 0)
// Image.file(
// File(imagepath), // 显示选择的图片文件
// fit: BoxFit.contain, // 设置图片填充方式为完整显示,保持宽高比例
// ),
// 背景横线
_buildBackgroundLines(),
// 签名画布
CustomPaint(
painter: SignaturePainter(points: _points),
size: Size.infinite,
),
// 提示文字
if (!_hasSignature)
const Center(
child: Text(
'请在此处签名',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
),
],
),
),
),
),
],
),
),
);
}
Widget _buildBackgroundLines() {
return LayoutBuilder(
builder: (context, constraints) {
return CustomPaint(
painter: BackgroundLinesPainter(),
size: Size(constraints.maxWidth, constraints.maxHeight),
);
},
);
}
Widget _buildActionButtons() {
return Padding(
padding: const EdgeInsets.only(left: 24,right: 24,top: 10,bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// 重签按钮
Expanded(
child: OutlinedButton(
onPressed: _clearSignature,
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 8),
side: const BorderSide(color: Colors.blue),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
'重签',
style: TextStyle(
fontSize: 16,
color: Colors.blue,
fontWeight: FontWeight.w500,
),
),
),
),
const SizedBox(width: 20),
// 确定按钮
Expanded(
child: ElevatedButton(
onPressed: _confirmSignature,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: const EdgeInsets.symmetric(vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
'确定',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
);
}
}
// 签名绘制器
class SignaturePainter extends CustomPainter {
final List<Offset?> points;
SignaturePainter({required this.points});
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 3.0;
for (int i = 0; i < points.length - 1; i++) {
if (points[i] != null && points[i + 1] != null) {
canvas.drawLine(points[i]!, points[i + 1]!, paint);
}
}
}
@override
bool shouldRepaint(SignaturePainter oldDelegate) => oldDelegate.points != points;
}
// 背景横线绘制器
class BackgroundLinesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
// ..color = Colors.grey[200]!
..color = Color.from(alpha: 0, red: 0, green: 0, blue: 0)!
..strokeWidth = 0;
// 绘制横线
for (double y = 40; y < size.height; y += 40) {
canvas.drawLine(
Offset(0, y),
Offset(size.width, y),
paint,
);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}