/// 发红包模板 library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:shirne_dialog/shirne_dialog.dart'; class RedPacket extends StatefulWidget { final bool flag; // true=群,false=单 final void Function(Map)? onSend; final int? maxNum; // 红包最大数量 const RedPacket({super.key, required this.flag, this.onSend, this.maxNum}); @override State createState() => _RedPacketState(); } class _RedPacketState extends State { final TextEditingController _amountController = TextEditingController(); final TextEditingController _maxNumController = TextEditingController(); final TextEditingController _remarkController = TextEditingController(); String amount = '0.00'; String remark = '恭喜发财,大吉大利'; // 限制只能输入数字和小数点,且最多两位小数 final List _decimalInputFormatters = [ FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')), ]; @override void dispose() { _amountController.dispose(); _maxNumController.dispose(); _remarkController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Material( type: MaterialType.transparency, child: Column( children: [ ListView( shrinkWrap: true, padding: const EdgeInsets.only(bottom: 50.0), children: [ if (widget.flag) const SizedBox(height: 10.0), if (widget.flag) Container( margin: const EdgeInsets.symmetric(horizontal: 15.0), padding: const EdgeInsets.symmetric(horizontal: 10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), child: Row( children: [ const Text('红包个数'), Expanded( child: TextField( maxLength: widget.maxNum, controller: _maxNumController, textAlign: TextAlign.right, buildCounter: (_, {required currentLength, maxLength, required isFocused}) => null, // 隐藏计数器 decoration: const InputDecoration( hintText: "填写个数", isDense: true, hintStyle: TextStyle(fontSize: 14.0), border: OutlineInputBorder(borderSide: BorderSide.none)), onChanged: (value) { // 输入的红包个数 setState(() { remark = value; }); }, ), ), const Text('个'), ], ), ), const SizedBox(height: 10.0), Container( margin: const EdgeInsets.symmetric(horizontal: 15.0), padding: const EdgeInsets.symmetric(horizontal: 10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), child: Row( children: [ const Text('总金额'), Expanded( child: TextField( controller: _amountController, keyboardType: const TextInputType.numberWithOptions(decimal: true), textAlign: TextAlign.right, inputFormatters: _decimalInputFormatters, maxLength: 6, buildCounter: (_, {required currentLength, maxLength, required isFocused}) => null, // 隐藏计数器 decoration: const InputDecoration( hintText: "¥0.00", isDense: true, hintStyle: TextStyle(fontSize: 14.0), border: OutlineInputBorder(borderSide: BorderSide.none)), onChanged: (value) { double val = double.tryParse(value) ?? 0.0; if (val > 200) { _amountController.text = '200'; val = 200; } setState(() { amount = val.toStringAsFixed(2); }); }, ), ), const Text('元'), ], ), ), const SizedBox(height: 10.0), Container( margin: const EdgeInsets.symmetric(horizontal: 15.0), padding: const EdgeInsets.symmetric(horizontal: 10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), child: Row( children: [ const Text('留言'), Expanded( child: TextField( maxLines: null, maxLength: 16, controller: _remarkController, keyboardType: TextInputType.multiline, textAlign: TextAlign.right, buildCounter: (_, {required currentLength, maxLength, required isFocused}) => null, // 隐藏计数器 decoration: const InputDecoration( hintText: "恭喜发财,大吉大利", isDense: true, hintStyle: TextStyle(fontSize: 14.0), border: OutlineInputBorder(borderSide: BorderSide.none)), onChanged: (value) { // 留言内容 setState(() { if (value.isEmpty) { remark = '恭喜发财,大吉大利'; } else { remark = value; } }); }, ), ), ], ), ), const SizedBox(height: 30.0), Row( mainAxisAlignment: MainAxisAlignment.center, children: [const Text('¥', style: TextStyle(fontSize: 24.0)), Text(amount, style: const TextStyle(fontSize: 36.0))]), const SizedBox( height: 20.0, ), UnconstrainedBox( constrainedAxis: Axis.vertical, child: FilledButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.all(Color(0xFFFF7F43)), padding: WidgetStateProperty.all(EdgeInsets.zero), minimumSize: WidgetStateProperty.all(const Size(180.0, 45.0)), shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0))), ), onPressed: () { double amountDouble = double.tryParse(amount) ?? 0.0; if (amountDouble > 0) { //发送红包 widget.onSend!( { 'maxNum': widget.maxNum ?? 1, 'amount': amount, 'remark': remark, }, ); } else { final baseStyle = MyDialog.theme.toastStyle?.top(); MyDialog.toast( '未输入金额', icon: const Icon(Icons.check_circle), duration: Duration(milliseconds: 5000), style: baseStyle?.copyWith( backgroundColor: Colors.red.withAlpha(200), ), ); } }, child: const Text( '塞钱进红包', style: TextStyle(fontSize: 16.0), ), ), ), const SizedBox( height: 10.0, ), const Align( alignment: Alignment.center, child: Text( '未领取的红包,将于24小时后发起退款', style: TextStyle(color: Colors.grey, fontSize: 12.0), ), ), ], ), ], ), ); } }