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);
        },
      ),
    );
  }
}

防抖就是防止抖动,避免事件的重复触发。
如果某一事件被连续快速地触发多次,只会执行最后那一次。适合输入框输入后自动搜索回调

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;
    });
  }

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值