Flutter实现点击搜索图标后切换显示清除/搜索图标的需求
实现点击触发的搜索/清除切换功能
关键改动说明
- 新增
TextEditingController管理输入框文本,替代原onChange实时更新逻辑,确保仅点击操作触发状态变化 - 新增
showClearIcon布尔变量,控制搜索/清除图标的切换显示 - 重构搜索与清除逻辑,严格通过点击事件触发
修改后的完整代码片段
class _OverViewState extends State<OverView> { OverViewController overViewController = OverViewController(); List<House> houses = []; String searchText = ''; bool isLoading = true; // 新增输入控制器,管理文本框内容 final TextEditingController _searchController = TextEditingController(); // 控制显示搜索图标还是清除图标 bool showClearIcon = false; @override void initState() { super.initState(); getHouses(); checkLocationPermission(); } @override void dispose() { // 销毁控制器,避免内存泄漏 _searchController.dispose(); super.dispose(); } void getHouses() async { await overViewController.fetchSortedHouses(); houses = overViewController.filterHouses(searchText); isLoading = false; setState(() {}); } // 执行搜索逻辑:获取输入框文本、过滤数据、切换显示清除图标 void performSearch() { setState(() { searchText = _searchController.text.trim(); houses = overViewController.filterHouses(searchText); // 只有输入非空时才显示清除图标 showClearIcon = searchText.isNotEmpty; }); } // 执行清除逻辑:清空文本、重置数据、切换回搜索图标 void clearSearch() { setState(() { _searchController.clear(); searchText = ''; // 重新获取全量数据(或直接过滤空文本) houses = overViewController.filterHouses(searchText); showClearIcon = false; }); } void checkLocationPermission() async { final bool locationAccessGranted = await overViewController.authorizeLocationAccess(); if (locationAccessGranted) { await overViewController.getCurrentLocation(); getHouses(); } setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( body: Container( color: const Color(0xFFEBEBEB), child: Column( children: [ Container( child: Padding( padding: const EdgeInsets.all(10.0), child: Container( decoration: BoxDecoration( color: const Color(0x33000000), borderRadius: BorderRadius.circular(10.0), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Row( children: [ Expanded( child: TextField( controller: _searchController, // 绑定控制器 // 移除原onChange,避免实时触发 decoration: const InputDecoration( hintText: 'Search for something', hintStyle: TextStyle( color: Color(0x66000000), ), border: InputBorder.none, ), ), ), // 根据showClearIcon切换图标 GestureDetector( onTap: showClearIcon ? clearSearch : performSearch, child: showClearIcon ? SvgPicture.asset( 'assets/icons/ic_clear.svg', // 替换为你的清除图标路径 width: 25, height: 25, color: const Color(0x66000000), ) : SvgPicture.asset( 'assets/icons/ic_search.svg', width: 25, height: 25, color: const Color(0x66000000), ), ), ], ), ), ), ), ), // 下方列表展示 isLoading ? const Center(child: CircularProgressIndicator()) : Expanded( child: ListView.builder( itemCount: houses.length, itemBuilder: (context, index) { // 替换为你的列表项UI实现 return ListTile(title: Text(houses[index].name)); }, ), ) ], ), ), ); } }
核心逻辑说明
- 搜索触发:点击搜索图标时,读取输入框当前文本,执行数据过滤并切换到清除图标(仅当输入非空时)
- 清除触发:点击清除图标时,清空输入框文本,重置数据为全量列表,切换回搜索图标
- 输入管理:通过
TextEditingController统一控制文本内容,避免onChange实时更新带来的不必要状态刷新
内容的提问来源于stack exchange,提问作者ThatGuy1234
相关产品推荐
相关产品推荐

