Hibok
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

120 lines
2.9 KiB

  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. /// Custom Search input field, showing the search and clear icons.
  4. class SearchInput extends StatefulWidget {
  5. final ValueChanged<String> onSearchInput;
  6. final Key searchInputKey;
  7. SearchInput(
  8. this.onSearchInput, {
  9. Key key,
  10. this.searchInputKey,
  11. }) : super(key: key);
  12. @override
  13. State<StatefulWidget> createState() {
  14. return SearchInputState(onSearchInput);
  15. }
  16. }
  17. class SearchInputState extends State {
  18. final ValueChanged<String> onSearchInput;
  19. TextEditingController editController = TextEditingController();
  20. Timer debouncer;
  21. bool hasSearchEntry = false;
  22. SearchInputState(this.onSearchInput);
  23. @override
  24. void initState() {
  25. super.initState();
  26. editController.addListener(onSearchInputChange);
  27. }
  28. @override
  29. void dispose() {
  30. editController.removeListener(onSearchInputChange);
  31. editController.dispose();
  32. super.dispose();
  33. }
  34. void onSearchInputChange() {
  35. if (editController.text.isEmpty) {
  36. debouncer?.cancel();
  37. onSearchInput(editController.text);
  38. return;
  39. }
  40. if (debouncer?.isActive ?? false) {
  41. debouncer.cancel();
  42. }
  43. debouncer = Timer(Duration(milliseconds: 500), () {
  44. onSearchInput(editController.text);
  45. });
  46. }
  47. @override
  48. Widget build(BuildContext context) {
  49. return Container(
  50. padding: EdgeInsets.symmetric(
  51. horizontal: 8,
  52. ),
  53. child: Row(
  54. children: <Widget>[
  55. Icon(
  56. Icons.search,
  57. color: Colors.black,
  58. ),
  59. SizedBox(
  60. width: 8,
  61. ),
  62. Expanded(
  63. child: TextField(
  64. keyboardAppearance: Brightness.light,
  65. style: TextStyle(textBaseline: TextBaseline.alphabetic),
  66. decoration: InputDecoration(
  67. hintText: '搜索位置',
  68. border: InputBorder.none,
  69. ),
  70. controller: editController,
  71. onChanged: (value) {
  72. setState(() {
  73. hasSearchEntry = value.isNotEmpty;
  74. });
  75. },
  76. ),
  77. ),
  78. SizedBox(
  79. width: 8,
  80. ),
  81. hasSearchEntry
  82. ? GestureDetector(
  83. child: Icon(
  84. Icons.clear,
  85. color: Colors.black,
  86. ),
  87. onTap: () {
  88. editController.clear();
  89. setState(() {
  90. hasSearchEntry = false;
  91. });
  92. },
  93. )
  94. : SizedBox(),
  95. ],
  96. ),
  97. decoration: BoxDecoration(
  98. borderRadius: BorderRadius.circular(16),
  99. color: Colors.grey[100],
  100. ),
  101. );
  102. }
  103. }