dart 如何用键盘控制自动完成控件

eqoofvh9  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(66)

我使用的自动完成小部件向用户显示建议,到目前为止一切顺利,问题是,我的应用程序还支持网络,我想建议可以通过键盘控制,即,上下箭头移动选项,并输入确认所选选项.我如何才能做到这一点?
这是我的代码的可执行摘录:

class _MyHomePageState extends State<MyHomePage> {
  final controller = TextEditingController();
  final focus = FocusNode();
  bool loadingAutocomplete = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: RawAutocomplete(
        textEditingController: controller,
        focusNode: focus,
        optionsBuilder: (TextEditingValue textEditingValue) async {
          return getCities(textEditingValue.text);
        },
        fieldViewBuilder: (BuildContext context,
            TextEditingController controller,
            FocusNode focusNode,
            VoidCallback onFieldSubmitted) {
          return TextField(
              controller: controller,
              focusNode: focusNode,
              onSubmitted: (value) {
                focusNode.requestFocus();
              },
              decoration: InputDecoration(
                labelText: 'Cities',
              ));
        },
        optionsViewBuilder: (context, onSelected, options) => Padding(
          padding: const EdgeInsets.only(top: 4),
          child: Align(
            alignment: Alignment.topLeft,
            child: Material(
              color: Colors.white,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(bottom: Radius.circular(4)),
              ),
              child: SizedBox(
                width: 300,
                child: ListView.builder(
                  padding: EdgeInsets.zero,
                  itemCount: options.length,
                  shrinkWrap: false,
                  itemBuilder: (BuildContext context, int index) {
                    final String option = options.elementAt(index);

                    return InkWell(
                      onTap: () => onSelected(option),
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: Text(option),
                      ),
                    );
                  },
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

  Future<List<String>> getCities(String value) async {
    // Simulate a delay
    await Future.delayed(Duration(seconds: 1));

    // List of cities
    List<String> cities = [
      'New York',
      'Los Angeles',
      'Chicago',
      'Houston',
      'Phoenix',
      'Philadelphia',
      'San Antonio',
      'San Diego',
      'Dallas',
      'San Jose'
    ];

    return cities
        .where((element) => element.toLowerCase().contains(value))
        .toList();
  }
}
pu3pd22g

pu3pd22g1#

试试这个,我通常用的。您可以自定义意见箱的大小或任何您想要的。

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

  @override
  Widget build(BuildContext context) {
    final List<String> maincategories = [ "Habib", "Karim", "Rahim", "Shen shu", "Nafis", "Alex", "Abdur Rahman" ];
    //const textStyle = TextStyle(color: Colors.white);
    return Scaffold(
      // resizeToAvoidBottomInset: false,
      appBar: AppBar(title: const Text("Test App")),
      body: Center(
        child: SizedBox(
          width: (MediaQuery.of(context).size.width * (0.8)),
          child: LayoutBuilder(
            builder: (context, constraints) => Autocomplete<String>(
              optionsViewBuilder: (context, onSelected, options) => Align(
                alignment: Alignment.topLeft,
                child: Material(
                  shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.vertical(
                        bottom: Radius.circular(10), top: Radius.circular(10)),
                  ),
                  child: Container(
                    decoration: BoxDecoration(
                        border: Border.all(color: Colors.grey, width: 2),
                        borderRadius:
                            const BorderRadius.all(Radius.circular(10)),
                        color: const Color.fromARGB(100, 220, 220, 220)),
                    height: 52.0 * min(5, options.length),
                    width: constraints.biggest.width,
                    child: ListView.builder(
                      padding: EdgeInsets.zero,
                      itemCount: options.length,
                      shrinkWrap: true,
                      itemBuilder: (BuildContext context, int index) {
                        final String option = options.elementAt(index);
                        return InkWell(
                          onTap: () => onSelected(option),
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: Text(option),
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ),
              optionsBuilder: (TextEditingValue textEditingValue) {
                return maincategories.where((String entry) {
                  if (textEditingValue.text.length > entry.length) {
                    return false;
                  } else {
                    return textEditingValue.text.toLowerCase() ==
                        entry
                            .substring(0, textEditingValue.text.length)
                            .toLowerCase();
                  }
                });
              },
              fieldViewBuilder: (context, textEditingController, focusNode,
                  onFieldSubmitted) {
                return TextField(
                  focusNode: focusNode,
                  controller: textEditingController,
                  onEditingComplete: onFieldSubmitted,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(10)),
                    fillColor: Colors.white,
                    filled: true,
                    hintText: "Select main category",
                    // errorText: "Error text",
                    contentPadding: EdgeInsets.symmetric(
                        vertical:
                            (MediaQuery.of(context).size.height * (0.025)),
                        horizontal: 10),
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

相关问题