dialog_input.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:get/get.dart';
  4. import 'alert_dialog.dart';
  5. /// 小弹窗输入
  6. class VDialogInput extends StatelessWidget {
  7. /// 标题
  8. final String? title;
  9. /// 描述
  10. final String? description;
  11. /// 输入占位符
  12. final String? placeholder;
  13. /// 初始值
  14. final String? initialValue;
  15. /// 是否为富文本框
  16. final int? maxLines;
  17. /// 当前输入框的高度
  18. final double? inputHeight;
  19. ///校验文本是否合法,不合法无法提交
  20. final bool Function(String)? onConfirmVerification;
  21. ///是否能点击蒙层取消弹窗
  22. final bool showCancel;
  23. final List<TextInputFormatter>? inputFormatters;
  24. final TextInputType? keyboardType;
  25. const VDialogInput({
  26. super.key,
  27. this.title,
  28. this.description,
  29. this.placeholder,
  30. this.initialValue,
  31. this.maxLines = 1,
  32. this.inputHeight = 56,
  33. this.onConfirmVerification,
  34. this.inputFormatters,
  35. this.showCancel = false,
  36. this.keyboardType,
  37. });
  38. Future<String?> show<String>() => VAlertDialog.showDialog<String>(this);
  39. @override
  40. Widget build(BuildContext context) {
  41. final controller = TextEditingController(text: initialValue);
  42. return VAlertDialog(
  43. title: title,
  44. width: 440,
  45. contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
  46. content: _buildContent(context, controller),
  47. showCancel: showCancel,
  48. onConfirm: () {
  49. if (onConfirmVerification != null) {
  50. FocusScope.of(context).nextFocus();
  51. bool isValid = onConfirmVerification!.call(controller.text);
  52. if (isValid) {
  53. Get.back(result: controller.text);
  54. }
  55. } else {
  56. Get.back(result: controller.text);
  57. }
  58. },
  59. );
  60. }
  61. Widget _buildContent(
  62. BuildContext context,
  63. TextEditingController controller,
  64. ) {
  65. final children = <Widget>[];
  66. if (description != null) {
  67. children.add(
  68. Padding(
  69. padding: const EdgeInsets.symmetric(horizontal: 4),
  70. child: Text(
  71. description!,
  72. style: const TextStyle(color: Colors.black87, fontSize: 18),
  73. ),
  74. ),
  75. );
  76. children.add(const SizedBox(height: 8));
  77. } else {
  78. children.add(const SizedBox(height: 12));
  79. }
  80. children.add(_buildInputWidget(context, controller));
  81. return SingleChildScrollView(
  82. child: Column(
  83. mainAxisSize: MainAxisSize.min,
  84. crossAxisAlignment: CrossAxisAlignment.start,
  85. children: children,
  86. ),
  87. );
  88. }
  89. Widget _buildInputWidget(
  90. BuildContext context,
  91. TextEditingController controller,
  92. ) {
  93. const fontSize = 20.0;
  94. return SizedBox(
  95. height: inputHeight,
  96. child: TextField(
  97. controller: controller,
  98. readOnly: false,
  99. autofocus: true,
  100. maxLines: maxLines,
  101. keyboardType: keyboardType,
  102. inputFormatters: inputFormatters,
  103. style: const TextStyle(fontSize: fontSize),
  104. decoration: InputDecoration(
  105. border: const UnderlineInputBorder(
  106. borderRadius: BorderRadius.zero,
  107. borderSide: BorderSide(),
  108. ),
  109. enabledBorder: const UnderlineInputBorder(
  110. borderRadius: BorderRadius.zero,
  111. borderSide: BorderSide(
  112. color: Colors.black54,
  113. ),
  114. ),
  115. focusedBorder: UnderlineInputBorder(
  116. borderRadius: BorderRadius.zero,
  117. borderSide: BorderSide(
  118. color: Theme.of(context).primaryColor.withOpacity(.4),
  119. ),
  120. ),
  121. filled: true,
  122. fillColor: Colors.white,
  123. contentPadding: const EdgeInsets.symmetric(
  124. vertical: 8,
  125. horizontal: 8,
  126. ),
  127. hintStyle: const TextStyle(fontSize: fontSize),
  128. labelStyle: const TextStyle(fontSize: fontSize),
  129. hintText: placeholder,
  130. isCollapsed: true,
  131. ),
  132. onSubmitted: (value) {
  133. if (onConfirmVerification != null) {
  134. bool isValid = onConfirmVerification!.call(value);
  135. if (isValid) {
  136. Get.back(result: value);
  137. }
  138. } else {
  139. Get.back(result: value);
  140. }
  141. },
  142. ),
  143. );
  144. }
  145. }