簡體   English   中英

Flutter - 在一次調用 setState() 后更新同級小部件

[英]Flutter - Update sibling Widget after calling setState() in one

我有一個對話框小部件,那里有一個按鈕和文本字段。 按下按鈕時,有一個函數至setState()和變量更改。 我沒有在文本字段的屏幕上立即看到這些更改,我需要再次關閉並打開 Dialog。 為什么以及如何實現它(所以整個班級/父級都將被重建?(這是關於“獲取位置”按鈕和下一個字段)

class MyDialog extends StatefulWidget {
  MyDialogState createState() => MyDialogState();
}

class MyDialogState extends State<MyDialog> {
  String userLocation;
  double sleepLength;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        showDialog(
            context: context,
            builder: (context) {
              return Dialog(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(30)
                  ),
                  elevation: 20,
                  child: ListView(
                    children: <Widget>[
                      FlatButton(
                        child: Text("Get location $userLocation"),
                        onPressed: () {
                          final Geolocator geolocator = Geolocator();
                          geolocator
                            .getCurrentPosition()
                            .then((Position position) async {
                              List<Placemark> place = await geolocator
                                .placemarkFromCoordinates(position.latitude, position.longitude);
                              Placemark p = place[0];

                              setState(() {
                                //userLocation = "${p.locality}, ${p.country}";
                                userLocation = Random().nextInt(10).toString();
                                print("A");

                              });

                          }).catchError((e) {
                            print("------------");
                            print(e);
                            print("------------");
                          });
                        },
                      ),
                      Padding(
                        padding: EdgeInsets.all(10),
                        child: Center(child: Text("$userLocation"))
                      ),
                      Divider(),
                      FlatButton(
                        child: Text("Set sleep length"),
                        onPressed: () {
                          //TODO
                        },
                      ),
                      Padding(
                          padding: EdgeInsets.all(10),
                          child: Center(child: Text("$sleepLength"))
                      ),
                      Divider(),
                    ],
                  )
              );
            }
        );
      },
      child: Icon(
          Icons.settings
      ),
      backgroundColor: Colors.black12,
    );
  }
}

在此處輸入圖片說明

在我的情況下StatefulBuilder工作。 StatefulBuilder最適用於您擁有中/大型小部件樹並且需要為該樹的一小部分引入狀態的情況。

StatefulBuilder包裹你的孩子希望它有幫助..

您必須使用return StatefulBuilder builder: ...包裝 Dialog return StatefulBuilder builder: ...
並仔細考慮}); 因為在這種情況下它是一個長字符串

代碼片段

 builder: (BuildContext context) {
      return StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {

          return Dialog(
              ...
          );

        },
      );

您使用StatefulBuilder的代碼

class MyDialog extends StatefulWidget {
  MyDialogState createState() => MyDialogState();
}

class MyDialogState extends State<MyDialog> {
  String userLocation;
  double sleepLength;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        showDialog(
            context: context,
            builder: (context) {
              return StatefulBuilder(
                  builder: (BuildContext context, StateSetter setState) {
                return Dialog(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30)),
                    elevation: 20,
                    child: ListView(
                      children: <Widget>[
                        FlatButton(
                          child: Text("Get location $userLocation"),
                          onPressed: () {
                            final Geolocator geolocator = Geolocator();
                            geolocator
                                .getCurrentPosition()
                                .then((Position position) async {
                              List<Placemark> place =
                                  await geolocator.placemarkFromCoordinates(
                                      position.latitude, position.longitude);
                              Placemark p = place[0];

                              setState(() {
                                //userLocation = "${p.locality}, ${p.country}";
                                userLocation = Random().nextInt(10).toString();
                                print("A");
                              });
                            }).catchError((e) {
                              print("------------");
                              print(e);
                              print("------------");
                            });
                          },
                        ),
                        Padding(
                            padding: EdgeInsets.all(10),
                            child: Center(child: Text("$userLocation"))),
                        Divider(),
                        FlatButton(
                          child: Text("Set sleep length"),
                          onPressed: () {
                            //TODO
                          },
                        ),
                        Padding(
                            padding: EdgeInsets.all(10),
                            child: Center(child: Text("$sleepLength"))),
                        Divider(),
                      ],
                    ));
              });
            });
      },
      child: Icon(Icons.settings),
      backgroundColor: Colors.black12,
    );
  }
}

使用StatefulBuilder可以解決這個問題

將您的MyDialogState替換為:

class MyDialogState extends State<MyDialog> {
  String userLocation;
  double sleepLength;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        showDialog(
            context: context,
            builder: (context) {
              return Dialog(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(30)
                  ),
                  elevation: 20,
                  child: StatefulBuilder(
                    builder: (BuildContext context, StateSetter setState) {
                      return ListView(
                      children: <Widget>[
                        FlatButton(
                          child: Text("Get location $userLocation"),
                          onPressed: () {
                            final Geolocator geolocator = Geolocator();
                            geolocator
                              .getCurrentPosition()
                              .then((Position position) async {
                                List<Placemark> place = await geolocator
                                  .placemarkFromCoordinates(position.latitude, position.longitude);
                                Placemark p = place[0];

                                setState(() {
                                  //userLocation = "${p.locality}, ${p.country}";
                                  userLocation = Random().nextInt(10).toString();
                                  print("A");

                                });

                            }).catchError((e) {
                              print("------------");
                              print(e);
                              print("------------");
                            });
                          },
                        ),
                        Padding(
                          padding: EdgeInsets.all(10),
                          child: Center(child: Text("$userLocation"))
                        ),
                        Divider(),
                        FlatButton(
                          child: Text("Set sleep length"),
                          onPressed: () {
                            //TODO
                          },
                        ),
                        Padding(
                            padding: EdgeInsets.all(10),
                            child: Center(child: Text("$sleepLength"))
                        ),
                        Divider(),
                      ],
                    );
                    },
                  )
              );
            }
        );
      },
      child: Icon(
          Icons.settings
      ),
      backgroundColor: Colors.black12,
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM