flutter 搜索框实现,键盘搜索按钮,清空,防抖

复制代码
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import 'package:sy_project/config/app_colors.dart';
import 'package:sy_project/core/assets.dart';

/// 搜索textview
class CustomSearchBarInput extends StatefulWidget {
  // 回调函数
  final Function(String) onSubmitted;
  final String hintLabel;

  const CustomSearchBarInput(
      {required this.hintLabel, required this.onSubmitted, super.key});

  @override
  State<CustomSearchBarInput> createState() => _CustomSearchBarInputState();
}

class _CustomSearchBarInputState extends State<CustomSearchBarInput> {
  // 焦点对象
  // FocusNode _focusNode = FocusNode();
  // 文本的值
  String searchVal = '';
  //用于清空输入框
  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    //  获取焦点
    // WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    //   _focusNode.requestFocus();
    // });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // color: AppColors.baseColor,
      // margin: EdgeInsets.all(ScreenHelper.pageHorizontalPadding()),
      height: 35.h,
      alignment: Alignment.centerLeft,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(20.h),
      ),
      child: TextField(
        textInputAction: TextInputAction.search,
        controller: _controller,
        textAlignVertical: TextAlignVertical.center,
        // //自动获取焦点
        // focusNode: _focusNode,
        autofocus: false,
        onTapOutside: (event){
          FocusScopeNode currentFocus = FocusScope.of(context);
          currentFocus.focusedChild?.unfocus();
        },
        decoration: InputDecoration(
            // contentPadding和border的设置是为了让TextField内容实现上下居中
            contentPadding: const EdgeInsets.all(0),
            hintText: widget.hintLabel,
            hintStyle: const TextStyle(color: AppColors.customColor_999),
            //取消下划线
            border: const OutlineInputBorder(borderSide: BorderSide.none),
            icon: Padding(
              padding: EdgeInsets.only(left: 10.w, right: 0),
              child: SvgPicture.asset(
                Assets.images.iconSearch,
                width: 12.w,
                height: 12.w,
              ),
            ),
            // icon: Padding(
            //     padding: const EdgeInsets.only(left: 0, top: 0),
            //     child: Icon(
            //       Icons.search,
            //       size: 18,
            //       color: Theme.of(context).primaryColor,
            //     )),
            //  关闭按钮,有值时才显示
            suffixIcon: searchVal.isNotEmpty
                ? IconButton(
                    icon: Icon(
                      Icons.close,
                      size: 15.w,
                    ),
                    onPressed: () {
                      //   清空内容
                      setState(() {
                        searchVal = '';
                        _controller.clear();
                      });
                    },
                  )
                : null),
        onChanged: (value) {
          setState(() {
            searchVal = value;
            // 防止抖动  搜索
            // VibrationThrottlingUtil.debounce(
            //     () => widget.onSubmitted(value), 1000);
          });
        },
        onSubmitted: (value) {
          widget.onSubmitted(value);
        },
      ),
    );
  }
}

防抖就是防止抖动,避免事件的重复触发。

如果某一事件被连续快速地触发多次,只会执行最后那一次。适合输入框输入后自动搜索回调

Dart 复制代码
class VibrationThrottlingUtil {
  static Timer? _debounceTimer;

  /// 防抖 (传入所要防抖的方法/回调与延迟时间)
  static void debounce(Function func, [int delay = 500]) {
    if (_debounceTimer != null) {
      _debounceTimer?.cancel();
    }
    _debounceTimer = Timer(Duration(milliseconds: delay), () {
      func.call();
      _debounceTimer = null;
    });
  }
相关推荐
只与明月听22 分钟前
LangChain 学习-掌握LangChain Core API
前端·人工智能·后端
Listen·Rain26 分钟前
Vue3中customRef详解
前端·javascript·vue.js
sugar__salt37 分钟前
Document 切割:RAG 知识库数据预处理实战
javascript·langchain·embedding·js·rag·cheerio
小粉粉hhh1 小时前
React(三)——Redux
前端·javascript·react.js
易知微EasyV数据可视化2 小时前
定制化3D组件开发:打造差异化孪生体验
前端·人工智能·经验分享·数字孪生
多加点辣也没关系2 小时前
JavaScript|第24章:事件循环与并发模型
开发语言·javascript·ecmascript
前端炒粉2 小时前
Vue2 SSE 流式对话完整前端代码
前端·sse·流式输出
子非鱼94272 小时前
06-Flutter 鸿蒙实战 06:上传后处理流程,照片识别、故事生成和状态刷新
学习·flutter·华为·harmonyos
BIM云平台开发3 小时前
【App.vue里跟踪页面跳转和用户ID】
开发语言·前端·javascript
汪汪大队u3 小时前
Zabbix 6.0 部署踩坑记:从启动失败到 Web 成功访问
前端·zabbix