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

Flutter GetX中如何创建同一Controller的多个独立实例

解决同一页面多搜索栏Controller冲突的方案

核心思路

不要复用同一个TextEditingController实例,每个搜索栏组件独立维护自己的Controller,确保输入状态完全隔离。

具体实现方法

方法1:自定义独立搜索栏组件(推荐)

把搜索栏封装成StatefulWidget,在组件内部创建并管理Controller,这样每个组件实例的状态都是独立的。

class YouTubeStyleSearchBar extends StatefulWidget {
  final String hintText;
  final Function(String)? onSearchSubmitted;

  const YouTubeStyleSearchBar({
    super.key,
    required this.hintText,
    this.onSearchSubmitted,
  });

  @override
  State<YouTubeStyleSearchBar> createState() => _YouTubeStyleSearchBarState();
}

class _YouTubeStyleSearchBarState extends State<YouTubeStyleSearchBar> {
  late final TextEditingController _searchController;

  @override
  void initState() {
    super.initState();
    // 每个组件实例单独创建Controller
    _searchController = TextEditingController();
  }

  @override
  void dispose() {
    // 组件销毁时释放Controller,避免内存泄漏
    _searchController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _searchController,
      decoration: InputDecoration(
        hintText: widget.hintText,
        prefixIcon: const Icon(Icons.search),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(24),
          borderSide: BorderSide.none,
        ),
        filled: true,
        fillColor: Colors.grey[200],
      ),
      onSubmitted: widget.onSearchSubmitted,
    );
  }
}

在页面中调用两次即可:

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          YouTubeStyleSearchBar(
            hintText: "搜索视频",
            onSearchSubmitted: (query) => print("第一个搜索栏提交:$query"),
          ),
          const SizedBox(height: 20),
          YouTubeStyleSearchBar(
            hintText: "搜索频道",
            onSearchSubmitted: (query) => print("第二个搜索栏提交:$query"),
          ),
        ],
      ),
    );
  }
}

方法2:父组件中创建多个Controller并传入

如果不想封装组件,也可以在父组件的State中创建两个独立的Controller,分别传给对应的搜索栏。

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late final TextEditingController _searchController1;
  late final TextEditingController _searchController2;

  @override
  void initState() {
    super.initState();
    _searchController1 = TextEditingController();
    _searchController2 = TextEditingController();
  }

  @override
  void dispose() {
    _searchController1.dispose();
    _searchController2.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          TextField(
            controller: _searchController1,
            decoration: const InputDecoration(
              hintText: "搜索视频",
              prefixIcon: Icon(Icons.search),
            ),
          ),
          const SizedBox(height: 20),
          TextField(
            controller: _searchController2,
            decoration: const InputDecoration(
              hintText: "搜索频道",
              prefixIcon: Icon(Icons.search),
            ),
          ),
        ],
      ),
    );
  }
}

关于tag失效的说明

如果之前尝试用tag方式没解决问题,大概率是因为你仍然复用了同一个Controller实例,而非为每个搜索栏创建全新的Controller对象。只要保证每个搜索栏绑定的Controller是独立的实例,就能彻底解决输入值冲突问题。

内容的提问来源于stack exchange,提问作者Vishal Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:50:01