flutter/lib/pages/chat/components/redpacket.dart
2025-08-21 10:50:38 +08:00

217 lines
9.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// 发红包模板
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<String, dynamic>)? onSend;
final int? maxNum; // 红包最大数量
const RedPacket({super.key, required this.flag, this.onSend, this.maxNum});
@override
State<RedPacket> createState() => _RedPacketState();
}
class _RedPacketState extends State<RedPacket> {
final TextEditingController _amountController = TextEditingController();
final TextEditingController _maxNumController = TextEditingController();
final TextEditingController _remarkController = TextEditingController();
String amount = '0.00';
String remark = '恭喜发财,大吉大利';
// 限制只能输入数字和小数点,且最多两位小数
final List<TextInputFormatter> _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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[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),
),
),
],
),
],
),
);
}
}