【问题标题】:Flutter: Adding text from alert dialog to list viewFlutter:将文本从警报对话框添加到列表视图
【发布时间】:2020-12-08 20:39:30
【问题描述】:

我正在尝试将警报对话框中的用户输入添加到列表视图。每次我运行它时,警报对话框都会接受输入并且项目列表会更新,但列表视图不会更新。在警报对话框按钮上按 OK 后,应用程序的状态不会改变。请帮我解决这个问题,因为我是 Flutter 新手。

Future<String> createAlertDialog(BuildContext context) {
        //promise to return string
        TextEditingController customController =
            TextEditingController(); //new texteditingc object
        return showDialog(
            context: context,
            builder: (context) {
              return AlertDialog(
                title: Text("Enter URL: "),
                content: TextField(
                  controller: customController,
                ),
                actions: [
                  MaterialButton(
                    elevation: 5.0,
                    child: Text("OK"),
                    onPressed: () {
                      Navigator.of(context).pop(customController.text.toString());
                    },
                  )
                ],
              );
            });
      }

  

    @override
      Widget build(BuildContext context) {
        List item = List();
        item=['HI'];
        String temp;
        return Scaffold(
          appBar: AppBar(
            title: Text("Shortie"),
          ),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView(
              children: 
              
              item.map((element)=>Text(element)).toList(), 
              
              ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              createAlertDialog(context).then((onValue) {
                temp=onValue;
                print(temp);
                 
                
              });
              setState(() {
                item.add(temp);
                print(item);
              });
            },
            tooltip: 'Add URL',
            child: Icon(Icons.add),
          ),
        );

【问题讨论】:

  • 您想在列表中显示输入的 URL 对吗?
  • 是的,我想这样做

标签: android flutter flutter-layout


【解决方案1】:

如果您有新信息,您必须调用 setState() 来更新小部件。

尝试将您的 showDialog() 更改为:

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text("Enter URL: "),
          content: TextField(
             controller: customController,
          ),
          actions: [
            MaterialButton(
              elevation: 5.0,
              child: Text("OK"),
              onPressed: () {
                item.add(customController.text);
                setState((){});
                Navigator.of(context).pop();

            },
          )
        ],
      );
    });

这应该将元素添加到item 列表中,更新小部件然后弹出。刷新和弹出对话框之间的时间几乎是瞬时的,因此应该是平滑的。

此外,您可能想要使用ListView.builder,该类将根据您选择的列表元素的数量显示一个列表。

话虽如此,将ListView 更改为此可能会有所帮助:

    child: ListView.builder(
      itemCount: item.length,
      itemBuilder: (context, index) {
        return Text('${item.index}'),
        },
    ),  

【讨论】:

  • 进行上述更改并重新启动应用程序后,它就像一个魅力。干杯。感谢您的帮助。
【解决方案2】:

你应该使用await instate of then。并将item 作为类属性。您的 List 没有更新,因为每次调用 setState 时,构建函数都会重建,并且由于 item=['HI'] 这一行,项目的值设置为 ['HI']。

再次,当您使用 then 函数时,只有 then 函数内部的代码会在 future 完成时执行。这就是为什么在对话结束之前调用 setState 的原因。

在这里我对您的代码进行了一些更改:

  List item = List();
  String temp;
  Future<String> createAlertDialog(BuildContext context) {
    //promise to return string
    TextEditingController customController =
        TextEditingController(); //new texteditingc object
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text("Enter URL: "),
            content: TextField(
              controller: customController,
            ),
            actions: [
              MaterialButton(
                elevation: 5.0,
                child: Text("OK"),
                onPressed: () {
                  Navigator.of(context).pop(customController.text.toString());
                },
              )
            ],
          );
        });
  }


  @override
  void initState() {
    item = ['HI'];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Shortie"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView(
          children: item.map((element) => Text(element)).toList(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          temp = await createAlertDialog(context);
          setState(() {
            item.add(temp);
            print(item);
          });
        },
        tooltip: 'Add URL',
        child: Icon(Icons.add),
      ),
    );
  }

【讨论】:

    【解决方案3】:

    您可以使用provider package 并将AlertDialogListView 通信,方法是使用notifyListeners() 并使ListView 成为Provider 数据的Consumer

    有关该软件包的更多信息:https://pub.dev/documentation/provider/latest

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-10
      • 2012-04-03
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多