flutter_integrated_whb/lib/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart

235 lines
7.0 KiB
Dart
Raw Normal View History

2025-08-14 15:05:48 +08:00
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:qhd_prevention/customWidget/custom_button.dart';
class MultiTextFieldWithTitle extends StatefulWidget {
final String label;
final List<String> texts;
final bool isEditable;
final String hintText;
final double fontSize;
final bool isRequired;
final ValueChanged<List<String>> onTextsChanged;
const MultiTextFieldWithTitle({
super.key,
required this.label,
required this.isEditable,
required this.hintText,
required this.onTextsChanged,
this.fontSize = 15,
this.texts = const [],
this.isRequired = true,
});
@override
State<MultiTextFieldWithTitle> createState() =>
_MultiTextFieldWithTitleState();
}
class _MultiTextFieldWithTitleState extends State<MultiTextFieldWithTitle> {
final List<TextEditingController> _controllers = [];
final List<FocusNode> _focusNodes = [];
@override
void initState() {
super.initState();
// 延迟初始化,避免构建过程中调用 setState
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
_addTextField();
}
});
}
@override
void dispose() {
for (var controller in _controllers) {
controller.dispose();
}
for (var node in _focusNodes) {
node.dispose();
}
super.dispose();
}
void _addTextField() {
setState(() {
final newController = TextEditingController();
final newFocusNode = FocusNode();
newController.addListener(() {
widget.onTextsChanged(_getAllTexts());
});
_controllers.add(newController);
_focusNodes.add(newFocusNode);
widget.onTextsChanged(_getAllTexts());
});
}
void _removeTextField(int index) async {
if (_controllers.length <= 1) return;
await showDialog<String>(
context: context,
builder:
(_) => CustomAlertDialog(
title: '提示',
mode: DialogMode.text,
content: '确定删除检查情况吗?',
cancelText: '取消',
confirmText: '确定',
onConfirm: () {
setState(() {
_controllers[index].dispose();
_focusNodes[index].dispose();
_controllers.removeAt(index);
_focusNodes.removeAt(index);
widget.onTextsChanged(_getAllTexts());
});
},
),
);
}
List<String> _getAllTexts() {
return _controllers.map((c) => c.text).toList();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题行
InkWell(
child: Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Row(
children: [
if (widget.isRequired && widget.isEditable)
Text('* ', style: TextStyle(color: Colors.red)),
Flexible(
child: Text(
widget.label,
style: TextStyle(
fontSize: widget.fontSize,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
const SizedBox(width: 8),
if (widget.isEditable)
CustomButton(
text: " 添加 ",
height: 30,
padding: const EdgeInsets.symmetric(
vertical: 2,
horizontal: 5,
),
backgroundColor: Colors.blue,
onPressed: _addTextField,
),
],
),
),
const SizedBox(height: 8),
// 输入框区域 - 高度自适应
Column(
children: [
// 可编辑状态
if (widget.isEditable)
..._controllers.asMap().entries.map((entry) {
final index = entry.key;
return _buildTextFieldWithDelete(index);
}).toList(),
// 不可编辑状态
if (!widget.isEditable)
...widget.texts.map((c) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(
padding: const EdgeInsets.all(12),
width: double.maxFinite,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4),
),
child: Text(
c,
style: TextStyle(
fontSize: widget.fontSize,
color: Colors.grey[600],
),
),
),
);
}).toList(),
],
),
],
),
);
}
Widget _buildTextFieldWithDelete(int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Stack(
children: [
// 输入框
Padding(
padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
child: Container(
decoration: BoxDecoration(
border: BoxBorder.all(color: Colors.grey.shade300, width: 1),
borderRadius: BorderRadius.circular(4),
),
padding: EdgeInsets.symmetric(vertical: 10),
child: TextField(
controller: _controllers[index],
decoration: InputDecoration(hintText: widget.hintText),
focusNode: _focusNodes[index],
keyboardType: TextInputType.multiline,
maxLines: 3,
minLines: 3,
style: TextStyle(fontSize: widget.fontSize),
),
),
),
// 删除按钮(叠加在左上角)
if (index > 0)
Positioned(
top: 0,
left: 0,
child: GestureDetector(
onTap: () => _removeTextField(index),
child: Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.all(4),
child: const Icon(Icons.close, size: 10, color: Colors.white),
),
),
),
],
),
);
}
}