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
相关产品推荐
相关产品推荐

