带有复选框的ListView的Flutter搜索栏

wyyhbhjk  于 2023-02-09  发布在  Flutter
关注(0)|答案(1)|浏览(158)

我想创建一个这样的小部件。这包含文本字段,一旦在字段中键入一些内容,它将排序列表,并显示字段下面的结果。下面显示的结果列表也可以有一个复选框字段,从结果中选择多个项目。有任何内置的Flutter小部件,可以对这种情况有用吗?或任何其他包来实现这一点。
以下是屏幕截图供参考。

我尝试使用RawAutoComplete小部件。
下面是代码。

class SearchBarDemo extends StatelessWidget {
      const SearchBarDemo({super.key});
    
      static List<String> suggestons = [
        "USA",
        "UK",
        "Uganda",
        "Uruguay",
        "United Arab Emirates"
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: RawAutocomplete(
            optionsBuilder: (textEditingValue) {
              if (textEditingValue.text == '') {
                return const Iterable<String>.empty();
              } else {
                List<String> matches = <String>[];
                matches.addAll(suggestons);
    
                matches.retainWhere((s) {
                  return s
                      .toLowerCase()
                      .contains(textEditingValue.text.toLowerCase());
                });
                return matches;
              }
            },
            fieldViewBuilder:
                (context, textEditingController, focusNode, onFieldSubmitted) {
              return TextField(
                decoration: InputDecoration(
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(7),
                  ),
                  hintText: 'Search',
                  contentPadding: EdgeInsets.symmetric(
                      vertical: 8,
                      horizontal: 4), // EdgeInsets.only(top: 8, left: 5),
                  prefixIcon: Container(
                    margin: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      border: Border(
                        right: BorderSide(
                          color: Colors.grey.shade400,
                        ),
                      ),
                    ),
                    child: Icon(
                      Icons.search,
                      color: Colors.grey.shade400,
                    ),
                  ),
                ),
                controller: textEditingController,
                focusNode: focusNode,
                onSubmitted: (String value) {},
              );
            },
            onSelected: (selection) {},
            optionsViewBuilder: (context, onSelected, options) {
              return Material(
                child: SingleChildScrollView(
                  child: Column(
                    children: options.map((opt) {
                      return InkWell(
                        onTap: () {
                          onSelected(opt);
                        },
                        child: Column(
                          children: [
                            Container(
                              height: 50,
                              width: 250,
                              alignment: Alignment.topLeft,
                              child: Card(
                                child: SizedBox(
                                  child: ListTile(
                                    title: Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.spaceBetween,
                                      children: [
                                        Text(
                                          opt,
                                          style: TextStyle(fontSize: 12),
                                        ),
                                        Transform.scale(
                                          scale: 0.8,
                                          child: Checkbox(
                                            value: false,
                                            onChanged: (val) {},
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      );
                    }).toList(),
                  ),
                ),
              );
            },
          ),
        );
      }
    }

以上代码的输出为:它覆盖整个屏幕,并在中间显示结果内容。

rjjhvcjd

rjjhvcjd1#

您可以自定义过滤器逻辑。您也可能喜欢SearchDelegate-class

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

  @override
  State<SearchBarDemo> createState() => _SearchBarDemoState();
}

class _SearchBarDemoState extends State<SearchBarDemo> {
  static List<String> suggestons = [
    "USA",
    "UK",
    "Uganda",
    "Uruguay",
    "United Arab Emirates"
  ];

  List<String> filterItems = [];
  List<String> checkedItems = [];

  late final TextEditingController controller = TextEditingController()
    ..addListener(() {
      /// filter logic will be here
      final text = controller.text.trim();
      filterItems = suggestons
          .where(
              (element) => element.toLowerCase().startsWith(text.toLowerCase()))
          .toList();

      setState(() {});
    });

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      children: [
        CupertinoTextField(
          controller: controller,
        ),
        Expanded(
          child: ListView.builder(
              itemCount: filterItems.length,
              itemBuilder: (context, index) {
                final bool isChecked =
                    checkedItems.contains(filterItems[index]);
                return CheckboxListTile(
                  value: isChecked,
                  title: Text("${filterItems[index]}"),
                  onChanged: (value) {
                    if (isChecked) {
                      checkedItems.remove(filterItems[index]);
                    } else {
                      checkedItems.add(filterItems[index]);
                    }
                    setState(() {});
                  },
                );
              }),
        ),
      ],
    ));
  }
}

相关问题