ITextInput.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. ///自带删除的ITextField
  4. typedef void ITextFieldCallBack(String content);
  5. enum ITextInputType { text, multiline, number, phone, datetime, emailAddress, url, password }
  6. class ITextField extends StatefulWidget {
  7. final ITextInputType keyboardType;
  8. final int maxLines;
  9. final int maxLength;
  10. final String hintText;
  11. final TextStyle hintStyle;
  12. final ITextFieldCallBack fieldCallBack;
  13. final ITextFieldCallBack fieldSubmit;
  14. final Icon deleteIcon;
  15. final InputBorder inputBorder;
  16. final Widget prefixIcon;
  17. final TextStyle textStyle;
  18. final FormFieldValidator<String> validator;
  19. final TextStyle counterStyle;
  20. final String inputText;
  21. final bool autofocus;
  22. final TextInputAction textInputAction;
  23. final EdgeInsetsGeometry contentPadding;
  24. final FocusNode focusNode;
  25. final GestureTapCallback fileOnTap;
  26. final bool hasCancel;
  27. ITextField(
  28. {Key key,
  29. ITextInputType keyboardType = ITextInputType.text,
  30. this.maxLines = 1,
  31. this.maxLength,
  32. this.hintText,
  33. this.hintStyle,
  34. this.fieldCallBack,
  35. this.fieldSubmit,
  36. this.deleteIcon,
  37. this.inputBorder,
  38. this.textStyle,
  39. this.prefixIcon,
  40. this.validator,
  41. this.counterStyle,
  42. this.inputText = '',
  43. this.autofocus = false,
  44. this.textInputAction,
  45. this.contentPadding,
  46. this.focusNode,
  47. this.fileOnTap,
  48. this.hasCancel = false})
  49. : assert(maxLines == null || maxLines > 0),
  50. assert(maxLength == null || maxLength > 0),
  51. keyboardType = maxLines == 1 ? keyboardType : ITextInputType.multiline,
  52. super(key: key);
  53. @override
  54. State<StatefulWidget> createState() => _ITextFieldState();
  55. }
  56. class _ITextFieldState extends State<ITextField> {
  57. String _inputText = '';
  58. bool _hasdeleteIcon = false;
  59. bool _isNumber = false;
  60. bool _isPassword = false;
  61. FocusNode _focusNode = FocusNode();
  62. ///输入类型
  63. TextInputType _getTextInputType() {
  64. switch (widget.keyboardType) {
  65. case ITextInputType.text:
  66. return TextInputType.text;
  67. case ITextInputType.multiline:
  68. return TextInputType.multiline;
  69. case ITextInputType.number:
  70. _isNumber = true;
  71. return TextInputType.number;
  72. case ITextInputType.phone:
  73. _isNumber = true;
  74. return TextInputType.phone;
  75. case ITextInputType.datetime:
  76. return TextInputType.datetime;
  77. case ITextInputType.emailAddress:
  78. return TextInputType.emailAddress;
  79. case ITextInputType.url:
  80. return TextInputType.url;
  81. case ITextInputType.password:
  82. _isPassword = true;
  83. return TextInputType.text;
  84. default:
  85. return TextInputType.text;
  86. }
  87. }
  88. ///输入范围
  89. List<TextInputFormatter> _getTextInputFormatter() {
  90. return _isNumber
  91. ? <TextInputFormatter>[
  92. WhitelistingTextInputFormatter.digitsOnly,
  93. ]
  94. : null;
  95. }
  96. @override
  97. void initState() {
  98. super.initState();
  99. _inputText = widget.inputText != null ? widget.inputText : '';
  100. if (widget.focusNode != null) {
  101. _focusNode = widget.focusNode;
  102. }
  103. _focusNode.addListener(() {
  104. if (!_focusNode.hasFocus) {
  105. setState(() {
  106. _hasdeleteIcon = false;
  107. });
  108. } else {
  109. setState(() {
  110. _hasdeleteIcon = (_inputText.isNotEmpty);
  111. });
  112. }
  113. });
  114. }
  115. @override
  116. Widget build(BuildContext context) {
  117. TextEditingController _controller = TextEditingController.fromValue(
  118. TextEditingValue(text: _inputText, selection: TextSelection.fromPosition(TextPosition(affinity: TextAffinity.downstream, offset: _inputText.length))));
  119. TextField textField = TextField(
  120. autofocus: widget.autofocus,
  121. focusNode: _focusNode,
  122. controller: _controller,
  123. textInputAction: widget.textInputAction,
  124. cursorColor: Theme.of(context).primaryColor,
  125. decoration: InputDecoration(
  126. counterStyle: widget.counterStyle,
  127. hintStyle: widget.hintStyle,
  128. hintText: widget.hintText,
  129. border: widget.inputBorder != null ? widget.inputBorder : UnderlineInputBorder(),
  130. fillColor: Colors.transparent,
  131. filled: true,
  132. prefixIcon: widget.prefixIcon,
  133. contentPadding: widget.contentPadding,
  134. suffixIcon: _hasdeleteIcon
  135. ? Container(
  136. width: 18.0,
  137. height: 18.0,
  138. child: IconButton(
  139. alignment: Alignment.center,
  140. padding: const EdgeInsets.all(2.0),
  141. iconSize: 18.0,
  142. icon: widget.deleteIcon != null ? widget.deleteIcon : Icon(Icons.cancel),
  143. color: Color(0xFf727785),
  144. onPressed: () {
  145. setState(() {
  146. _inputText = '';
  147. _hasdeleteIcon = (_inputText.isNotEmpty);
  148. widget.fieldCallBack(_inputText);
  149. });
  150. },
  151. ),
  152. )
  153. : Text(''),
  154. ),
  155. onChanged: (str) {
  156. setState(() {
  157. _inputText = str;
  158. _hasdeleteIcon = (_inputText.isNotEmpty);
  159. widget.fieldCallBack(_inputText);
  160. });
  161. },
  162. onSubmitted: (str) {
  163. setState(() {
  164. widget.fieldSubmit(str);
  165. });
  166. },
  167. keyboardType: _getTextInputType(),
  168. maxLength: widget.maxLength,
  169. maxLines: widget.maxLines,
  170. inputFormatters: _getTextInputFormatter(),
  171. style: widget.textStyle,
  172. obscureText: _isPassword,
  173. onTap: () {
  174. widget.fileOnTap();
  175. },
  176. );
  177. if (!widget.hasCancel) {
  178. return textField;
  179. } else {
  180. return Row(
  181. children: <Widget>[
  182. Expanded(
  183. flex: 1,
  184. child: Container(
  185. height: 34,
  186. padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
  187. decoration: BoxDecoration(
  188. color: Colors.white,
  189. borderRadius: BorderRadius.all(Radius.circular(100)),
  190. ),
  191. child: textField),
  192. ),
  193. InkWell(
  194. child: Container(
  195. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 6),
  196. child: Text('取消', style: TextStyle(fontSize: 16, color: Colors.white)),
  197. ),
  198. onTap: () {
  199. Navigator.of(context).pop(true);
  200. // setState(() {
  201. // _inputText = '';
  202. // _hasdeleteIcon = (_inputText.isNotEmpty);
  203. // widget.fieldCallBack(_inputText);
  204. // _focusNode.unfocus();
  205. // });
  206. },
  207. )
  208. ],
  209. );
  210. }
  211. }
  212. }