Ich versuche, Benutzereingaben aus dem Warnungsdialog zur Listenansicht hinzuzufügen. Jedes Mal, wenn ich es ausführe, akzeptiert der Warndialog Eingaben und die Elementliste wird aktualisiert, aber die Listenansicht wird nicht aktualisiert. Der Status der App ändert sich nicht, nachdem ich im Alarmdialog auf OK geklickt habe. Bitte helfen Sie mir bei diesem Problem, da ich neu im Flattern bin.

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),
          ),
        );
0
Maverick 2000 19 Aug. 2020 im 17:33

3 Antworten

Beste Antwort

Sie müssen setState () aufrufen, um ein Widget zu aktualisieren, wenn Sie neue Informationen haben.

Versuchen Sie, Ihr showDialog() wie folgt zu ändern:

    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();

            },
          )
        ],
      );
    });

Das sollte das Element zur item Liste hinzufügen, das Widget aktualisieren und dann pop. Der Zeitpunkt zwischen dem Aktualisieren und dem Aufrufen des Dialogfelds ist nahezu augenblicklich, sodass dies reibungslos erfolgen sollte.

Darüber hinaus möchten Sie möglicherweise ListView.builder verwenden, eine Klasse, die eine Liste anzeigt, die von der Anzahl der Elemente der Liste Ihrer Wahl abhängt.

Vor diesem Hintergrund könnte es in Zukunft hilfreich sein, das ListView in dieses zu ändern:

    child: ListView.builder(
      itemCount: item.length,
      itemBuilder: (context, index) {
        return Text('${item.index}'),
        },
    ),  
1
António Oliveira 19 Aug. 2020 im 14:53

Sie können das Anbieterpaket verwenden und das AlertDialog mit dem ListView von kommunizieren Verwenden von notifyListeners() und Erstellen von ListView zu Consumer der Provider-Daten.

Weitere Informationen zum Paket: https://pub.dev/documentation/provider/latest

0
MikeDedo 19 Aug. 2020 im 15:13

Sie sollten await Instate von then verwenden. Und machen Sie item als Klasseneigenschaft. Ihre Liste wird nicht aktualisiert, da bei jedem Aufruf von setState die Build-Funktion neu erstellt und der Wert des Elements aufgrund von item=['HI'] in dieser Zeile auf ['HI'] gesetzt wird.

Wenn Sie dann die Funktion verwenden, wird nur der Code innerhalb der Funktion ausgeführt, wenn die Zukunft abgeschlossen ist. Deshalb hat Ihr setState aufgerufen, bevor Ihr Dialog beendet wurde.

Hier ändere ich Ihren Code:

  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),
      ),
    );
  }
0
Tipu Sultan 19 Aug. 2020 im 14:52