You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义搜索组件如何添加loading属性并在onChanged中控制状态?

实现带加载状态的自定义搜索组件BtxtSearchNew

步骤1:完善组件的参数定义

首先需要把loading参数升级为组件的成员变量,确保父组件能传递该状态到子组件,同时规范参数类型避免动态类型风险:

class BtxtSearchNew extends StatefulWidget {
  const BtxtSearchNew({
    Key? key,
    required this.textController,
    this.onChanged,
    this.hintText = "Search",
    this.autoFocus,
    this.onSubmit,
    this.focusNode,
    this.loading = false, // 将loading改为可传入的参数
  }) : super(key: key);

  final TextEditingController textController;
  final ValueChanged<String>? onChanged; // 明确类型,替代dynamic
  final String hintText;
  final bool? autoFocus;
  final ValueChanged<String>? onSubmit;
  final FocusNode? focusNode;
  final bool loading; // 添加成员变量接收loading状态

  @override
  State<BtxtSearchNew> createState() => _BtxtSearchNewState();
}

步骤2:在组件内部根据loading状态渲染加载指示器

在组件的State类中,根据widget.loading的值决定是否显示加载组件(比如圆形进度条),将其嵌入到你原来的Row布局中:

class _BtxtSearchNewState extends State<BtxtSearchNew> {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: TextFormField(
            controller: widget.textController,
            onChanged: widget.onChanged,
            onFieldSubmitted: widget.onSubmit,
            focusNode: widget.focusNode,
            autofocus: widget.autoFocus ?? false,
            decoration: InputDecoration(
              hintText: widget.hintText,
              // 保留你原来的输入框装饰配置
            ),
          ),
        ),
        // 当loading为true时显示加载进度条
        if (widget.loading)
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: CircularProgressIndicator(strokeWidth: 2),
          ),
      ],
    );
  }
}

步骤3:在父组件中维护loading状态并传递给子组件

父组件需要自己维护loading的状态,通过setState更新状态,再传递给BtxtSearchNew组件:

// 假设父组件是一个StatefulWidget
class ParentPage extends StatefulWidget {
  @override
  _ParentPageState createState() => _ParentPageState();
}

class _ParentPageState extends State<ParentPage> {
  final TextEditingController searchInput = TextEditingController();
  bool _searchLoading = false;
  // 假设你的防抖器定义如下
  final Debouncer debouncer = Debouncer(milliseconds: 500);

  @override
  Widget build(BuildContext context) {
    return BtxtSearchNew(
      textController: searchInput,
      onChanged: (value) {
        // 开始搜索时更新loading状态为true
        setState(() {
          _searchLoading = true;
        });
        debouncer.call(() {
          // 执行你的搜索逻辑
          // controller.searchText.value = searchInput.text.toLowerCase();
          
          // 搜索完成后更新loading状态为false
          setState(() {
            _searchLoading = false;
          });
        });
      },
      hintText: "Search by Date or Employee Name or Employee ID",
      loading: _searchLoading, // 将父组件的状态传递给子组件
    );
  }
}

关键说明

你之前的写法无法生效,是因为父组件不能直接修改子组件的内部参数,必须通过父组件维护状态 + 参数传递的方式,让子组件根据父组件传入的loading值重新渲染,从而实现加载状态的切换。

内容的提问来源于stack exchange,提问作者Honey Last

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:12:45