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

Flutter Autocomplete如何取消默认选中第一项并将选中项设为null?

解决Flutter Autocomplete自动选中第一项的问题

要实现下拉列表无默认选中项、仅允许手动点击选择,且回车不触发选中,可以通过自定义optionsViewBuilder和控制TextField的键盘事件来实现,具体方案如下:

核心实现步骤

  • 用ValueNotifier跟踪选中索引,初始设为-1(表示无选中项)
  • 自定义选项视图,仅在手动点击时触发选中状态变化
  • 拦截输入框的回车事件,阻止默认的自动选中逻辑

完整代码示例

import 'package:flutter/material.dart';

void main() => runApp(const AutocompleteExampleApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Autocomplete无默认选中示例')),
        body: const Center(
          child: _CustomAutocomplete(),
        ),
      ),
    );
  }
}

class _CustomAutocomplete extends StatefulWidget {
  const _CustomAutocomplete();

  @override
  State<_CustomAutocomplete> createState() => _CustomAutocompleteState();
}

class _CustomAutocompleteState extends State<_CustomAutocomplete> {
  final TextEditingController _textEditingController = TextEditingController();
  final ValueNotifier<int> _selectedIndex = ValueNotifier(-1); // 初始无选中项

  static const List<String> _options = <String>[
    'aardvark', 'bobcat', 'chameleon',
    'dolphin', 'elephant', 'flamingo',
  ];

  @override
  void dispose() {
    _textEditingController.dispose();
    _selectedIndex.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Autocomplete<String>(
      controller: _textEditingController,
      optionsBuilder: (TextEditingValue textEditingValue) {
        if (textEditingValue.text.isEmpty) {
          return const Iterable<String>.empty();
        }
        return _options.where((String option) {
          return option.contains(textEditingValue.text.toLowerCase());
        });
      },
      // 自定义选项视图,控制选中逻辑
      optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
        return Align(
          alignment: Alignment.topLeft,
          child: Material(
            elevation: 4.0,
            child: SizedBox(
              height: 200.0,
              child: ListView.builder(
                padding: const EdgeInsets.all(8.0),
                itemCount: options.length,
                itemBuilder: (BuildContext context, int index) {
                  final String option = options.elementAt(index);
                  return ValueListenableBuilder<int>(
                    valueListenable: _selectedIndex,
                    builder: (context, selectedIdx, child) {
                      return InkWell(
                        onTap: () {
                          onSelected(option);
                          _selectedIndex.value = -1; // 选中后重置为无选中状态
                          _textEditingController.text = option;
                        },
                        child: Container(
                          color: selectedIdx == index ? Theme.of(context).focusColor : Colors.transparent,
                          padding: const EdgeInsets.all(16.0),
                          child: Text(option),
                        ),
                      );
                    },
                  );
                },
              ),
            ),
          ),
        );
      },
      // 自定义输入框,拦截回车事件
      fieldViewBuilder: (BuildContext context, TextEditingController textEditingController, FocusNode focusNode, VoidCallback onFieldSubmitted) {
        return TextField(
          controller: textEditingController,
          focusNode: focusNode,
          onSubmitted: (String value) {
            // 不执行任何操作,阻止默认回车选中逻辑
          },
          decoration: const InputDecoration(
            hintText: '输入字符搜索...',
            border: OutlineInputBorder(),
          ),
        );
      },
      onSelected: (String selection) {
        debugPrint('选中了: $selection');
      },
    );
  }
}

关键细节说明

  1. 选中状态控制:通过ValueNotifier<int>管理选中索引,初始值-1确保没有默认选中项,只有手动点击选项时才更新状态并触发选中回调。
  2. 选项视图自定义:用ValueListenableBuilder监听选中索引变化,动态切换选项的高亮样式,避免自动选中逻辑。
  3. 回车事件拦截:在输入框的onSubmitted回调中不做任何处理,彻底阻止回车自动选中第一项的默认行为。

设置完成后,输入字符时下拉列表正常展示匹配选项,但不会自动选中任何项,仅支持手动点击选择,按下回车也不会触发选中动作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:15:03