import 'package:flutter/material.dart'; import '../../ui/widget/nav.dart'; import '../../utils/ui_constant.dart'; import '../../utils/ui_utils.dart'; class SearchBar extends StatefulWidget { final String? hint; final String? text; final ValueChanged? onSubmit; final ValueChanged? onChange; final SearchController? searchController; SearchBar( {Key? key, this.hint, this.text, this.onSubmit, this.onChange, this.searchController}) : super(key: key); @override _SearchBarState createState() => _SearchBarState(); } class _SearchBarState extends State { final TextEditingController _searchKeyController = TextEditingController(); final FocusNode _focusNode = FocusNode(); bool _showClose = false; @override void initState() { super.initState(); _focusNode.addListener(() { if (!_focusNode.hasFocus) { // print('失去焦点'); setState(() { _showClose = false; }); } else { // print('得到焦点'); if (_searchKeyController.text.isNotEmpty) { setState(() { _showClose = true; }); } } }); if (widget.text != null) { _searchKeyController.text = widget.text!; } if (widget.searchController != null) { widget.searchController!.setData = (content) { _searchKeyController.text = content; _searchKeyController.selection=TextSelection.fromPosition(TextPosition( affinity: TextAffinity.downstream, offset: content.length)); }; } } @override void dispose() { _focusNode.unfocus(); super.dispose(); } @override Widget build(BuildContext context) { return Row( children: [ Container( width: 11, ), Expanded( child: Stack(children: [ Container( height: 34, decoration: BoxDecoration( color: Color(0xFFEEEDED), borderRadius: BorderRadius.circular(17)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 13, ), Image.asset( "assets/imgs/icon_search_home.png", height: 17, ), Expanded( child: TextField( cursorRadius: const Radius.circular(1), cursorColor: ColorConstant.theme, maxLines: 1, textInputAction: TextInputAction.search, style: TextStyle( color: Color(0xFF787878), ), decoration: InputDecoration( hintText: widget.hint, hintStyle: TextStyle( color: Color(0xFF787878), ), border: InputBorder.none, enabledBorder: InputBorder.none, disabledBorder: InputBorder.none, focusedBorder: InputBorder.none, contentPadding: EdgeInsets.fromLTRB(10, 0, 10, 12)), controller: _searchKeyController, focusNode: _focusNode, onSubmitted: (content) { if (widget.onSubmit != null) { widget.onSubmit!(content); } }, onChanged: (content) { if (content.isEmpty) { setState(() { _showClose = false; }); } else { setState(() { _showClose = true; }); } if (widget.onChange != null) { widget.onChange!(content); } }, )), Container( width: 13, ), ], ), ), _showClose ? Positioned( right: 5, top: 0, bottom: 0, child: InkWell( onTap: () { _searchKeyController.text = ""; setState(() { _showClose = false; }); }, child: Icon( Icons.highlight_off, color: Color(0xFF787878), ))) : Container() ])), InkWell( onTap: () { popPage(context); }, child: Container( height: 34, alignment: Alignment.center, padding: const EdgeInsets.only(left: 20, right: 20), child: const Text( "取消", style: TextStyle(color: Color(0xFFFF558D)), )), ) ], ); } } class SugguestSearchView extends StatefulWidget { final ValueChanged? onCancel; final ValueChanged? onItemClick; final List contentList; final SugguestSearchController? sugguestSearchController; SugguestSearchView( {Key? key, this.onCancel, this.onItemClick, required this.contentList, this.sugguestSearchController}) : super(key: key); @override _SugguestSearchViewState createState() => _SugguestSearchViewState(); } class _SugguestSearchViewState extends State { List contentList = []; bool _show = false; @override void initState() { super.initState(); contentList.addAll(widget.contentList); if (contentList.isNotEmpty) { setState(() { _show = true; }); } else { setState(() { _show = false; }); } bindController(); } void bindController() { if (widget.sugguestSearchController == null) { return; } widget.sugguestSearchController!.setData = (list) { setState(() { contentList = list; }); }; widget.sugguestSearchController!.setShow = (show) { setState(() { _show = show; }); }; } @override Widget build(BuildContext context) { return _show ? Positioned( top: MediaQuery.of(context).viewPadding.top + 39, child: InkWell( onTap: () { if (widget.onCancel != null) { setState(() { _show = false; }); widget.onCancel!(""); } }, child: Container( color: Colors.transparent, width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, padding: const EdgeInsets.fromLTRB(50, 0, 80, 0), margin: EdgeInsets.all(0), child: Column(children: [ Container( height: 40 * contentList.length + (contentList.length - 1) * DimenUtil.getOnePixel(context), decoration: const BoxDecoration( color: Color(0xFF999999), boxShadow: [ BoxShadow( color: Color(0x30000000), blurRadius: 10, offset: Offset(0, 3)) ]), child: ListView.builder( padding: EdgeInsets.all(0), itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () { if (widget.onItemClick != null) { widget.onItemClick!(contentList[index]); } }, child: getSuggestSearchItem(contentList[index])); }, itemCount: contentList.length, )), Expanded(child: Container()) ]), ), )) : Container(); } Widget getSuggestSearchItem(String text) { return Container( height: 40, alignment: Alignment.centerLeft, margin: EdgeInsets.only(bottom: DimenUtil.getOnePixel(context)), color: Colors.white, padding: EdgeInsets.fromLTRB(20, 0, 20, 0), child: Text( text, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 12, color: const Color(0xFF4A4A4A)), ), ); } } class SugguestSearchController { ValueChanged>? setData; ValueChanged? setShow; } class SearchController { ValueChanged? setData; }