简体   繁体   English

如何使用 statefulBuilder 在对话框内使用 setState() 更新 Listview.builder 中的文本字段搜索

[英]How to make a Textfield search in Listview.builder update with setState() inside a Dialog using statefulBuilder

I'm very new to flutter and I have found several videos and posts about AlertDialog and StatefulBuilder, however I do not understand how it works enough to apply it to my own scenario.我对 flutter 很陌生,我发现了几个关于 AlertDialog 和 StatefulBuilder 的视频和帖子,但是我不明白它是如何工作的,足以将它应用到我自己的场景中。

Essentially I have a class that stores a book name and book cover photo, and I have a custom search widget that builds a text field and filters through a List view of all the books.本质上,我有一个 class 存储书名和书籍封面照片,我有一个自定义搜索小部件,它构建一个文本字段并通过所有书籍的列表视图进行过滤。 I've tested the functionality of the code and it works as intended outside of the Dialog(), however, the when inside the Dialog() the state does not get updated and the search function does not work.我已经测试了代码的功能,它在 Dialog() 之外按预期工作,但是,当在 Dialog() 内部时,state 没有更新,搜索 function 不起作用。

Here is the script that I am trying to fix.这是我要修复的脚本。 I do import the search widget and the book list from other files.我确实从其他文件中导入了搜索小部件和书单。 Supposedly it's an easy fix with a StatefulBuilder, but I really can't seem to get a grasp on it.据说使用 StatefulBuilder 很容易解决,但我似乎真的无法掌握它。 Any help with specific examples and explanations with respect to my code would be really appreciated.对于我的代码的具体示例和解释的任何帮助将不胜感激。

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);
                            },
                          ),
                        ),
                      ],
                    )),
              ),
            ),
          ));
}

Based on the documentation Dialog has no implementation of the Materialapp.根据文档, Dialog没有 Materialapp 的实现。 Maybe you could change to AlertDialog or SimpleDialog.也许您可以更改为 AlertDialog 或 SimpleDialog。 Because of the use of Scaffold.因为使用了脚手架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM