【问题标题】:How to make a Textfield search in Listview.builder update with setState() inside a Dialog using statefulBuilder如何使用 statefulBuilder 在对话框内使用 setState() 更新 Listview.builder 中的文本字段搜索
【发布时间】:2022-01-17 12:18:44
【问题描述】:

我是 Flutter 的新手,我发现了几个关于 AlertDialog 和 StatefulBuilder 的视频和帖子,但是我不明白它是如何工作的,不足以将它应用到我自己的场景中。

基本上我有一个存储书名和书封面照片的类,我有一个自定义搜索小部件,它构建一个文本字段并通过所有书籍的列表视图进行过滤。我已经测试了代码的功能,它在 Dialog() 之外按预期工作,但是,当在 Dialog() 内部时,状态没有更新,搜索功能也不起作用。

这是我要修复的脚本。我确实从其他文件中导入了搜索小部件和书单。据说使用 StatefulBuilder 可以轻松解决问题,但我似乎真的无法掌握它。任何有关我的代码的具体示例和解释的帮助将不胜感激。

import 'package:flutter/material.dart';
import 'Universal Classes and Vars/List.dart';
import 'Widgets/searchWidget.dart';

class BuildTemplate extends StatefulWidget {
  @override
  _BuildTemplateState createState() => _BuildTemplateState();
}

class _BuildTemplateState extends State<BuildTemplate> {
  List<Book> currentTemplate = [];
  late List<Book> books;
  String searchText = '';

  void initState() {
    super.initState();

    books = bookList;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[100],
      appBar: AppBar(title: Text("New Page")),
      body: Stack(children: [
        Column(children: [
          Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            Text("Custom Template"),
            IconButton(onPressed: () {}, icon: Icon(Icons.add))
          ]),
          Expanded(
            child: SizedBox(
                width: 500,
                child: ListView.builder(
                    itemCount: currentTemplate.length + 1,
                    itemBuilder: (context, index) =>
                        index < currentTemplate.length
                            ? Card(
                                child: ListTile(
                                onTap: () {},
                                title: Text(currentTemplate[index].name),
                                leading: CircleAvatar(
                                  backgroundImage:
                                      AssetImage(currentTemplate[index].image),
                                ),
                              ))
                            : ElevatedButton(
                                child: Text("Add Element"),
                                style: ButtonStyle(),
                                onPressed: () {
                                  openDialog();
                                },
                              ))),
          ),
        ]),
      ]),
    );
  }

  Widget buildSearch() => SearchWidget(
        text: searchText,
        hintText: 'Search',
        onChanged: searchBook,
      );

  Widget buildBook(Book book) => Card(
          child: ListTile(
        onTap: () {},
        title: Text(book.name),
        leading: CircleAvatar(
          backgroundImage: AssetImage(book.image),
        ),
      ));

  void searchBook(String searchText) {
    final books = bookList.where((element) {
      final nameLower = element.name.toLowerCase();
      final searchLower = searchText.toLowerCase();
      return nameLower.contains(searchLower);
    }).toList();

    setState(() {
      this.searchText = searchText;
      this.books = books;
    });
  }

  openDialog() => showDialog(
      context: context,
      builder: (context) => StatefulBuilder(
            builder: (context, setState) => Dialog(
              child: Center(
                child: Container(
                    color: Colors.grey,
                    margin: EdgeInsets.symmetric(horizontal: 20, vertical: 30),
                    padding: EdgeInsets.all(15),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        buildSearch(),
                        SizedBox(
                          height: 10,
                        ),
                        Expanded(
                          child: ListView.builder(
                            itemCount: books.length,
                            itemBuilder: (context, index) {
                              final book = books[index];

                              return buildBook(book);
                            },
                          ),
                        ),
                      ],
                    )),
              ),
            ),
          ));
}

【问题讨论】:

    标签: flutter dart listview setstate


    【解决方案1】:

    根据文档Dialog 没有 Materialapp 的实现。也许您可以更改为 AlertDialog 或 SimpleDialog。因为使用了脚手架。

    【讨论】:

    • 我试过这个,我得到了完全相同的结果。我之所以使用,是因为我读到 AlertDialog 用于简单的弹出窗口,而 Dialog 是更复杂的弹出窗口。虽然看起来行为相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 2011-02-19
    • 2012-07-15
    • 2013-05-07
    相关资源
    最近更新 更多