如何将数据从 alertdialog 传递到 flutter 页面?

How to pass data from alertdialog to page in flutter?

我正在将数据从我的警报对话框传递到列表视图的项目。

在哪里可以找到有关它的信息?

我尝试将 TextEditingController 与导航路由一起使用。我使用了 this Tutorial

的材料

这是我的代码:

    class MeasurementsScreen extends StatefulWidget {
  @override
  _MeasurementsScreenState createState() => _MeasurementsScreenState();
}


class _MeasurementsScreenState extends State<MeasurementsScreen> {
  List<_ListItem> listItems;
  String lastSelectedValue;
  var name = ["Рост", "Вес"];
  var indication = ["Введите ваш рост", "Введите ваш вес"];
  TextEditingController customcintroller;

  void navigationPageProgrammTrainingHandler() {
    Navigator.of(context).push(MaterialPageRoute(
        builder: (BuildContext context) => ProgrammTrainingHandler()),
    );
  }
  @override
  void initState() {
    super.initState();
    initListItems();
  }

  Future<String> createAlertDialog(BuildContext context, int indexAl){
    customcintroller = TextEditingController();
    if(indexAl < 2){
      return showDialog(context: context, builder: (context){
        return AlertDialog(
          title: Text(name[indexAl]),
          content: TextField(
            textDirection: TextDirection.ltr,
            controller: customcintroller,
            style: TextStyle(
                color: Colors.lightGreen[400],
                fontSize: 18.5),
            decoration: InputDecoration(
              contentPadding: EdgeInsets.only(bottom: 4.0),
              labelText: indication[indexAl],
              alignLabelWithHint: false,
            ),
            keyboardType: TextInputType.phone,
            textInputAction: TextInputAction.done,
          ),
          actions: <Widget>[
            FlatButton(
              child: const Text('ОТМЕНА'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            FlatButton(
              child: const Text('ОК'),
              onPressed: () {
                Navigator.of(context).pop(customcintroller.text.toString());
              },
            ),
          ],
        );
      });
    } else if (indexAl > 1){
      navigationPageProgrammTrainingHandler();
    }

  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: Color(0xff2b2b2b),
      appBar: AppBar(
        title: Text(
          'Замеры',
          style: new TextStyle(
            color: Colors.white,

          ),),
        leading: IconButton(
          icon:Icon(Icons.arrow_back),
          color: Colors.white ,
          onPressed:() => Navigator.of(context).pop(),
        ),
      ),
      body: ListView.builder(
        physics: BouncingScrollPhysics(),
        itemCount: listItems.length,
        itemBuilder: (BuildContext ctxt, int index){
          return GestureDetector(
              child: listItems[index],
              onTap: () {
                  createAlertDialog(context, index).then((onValue){

                  });
              }
          );
        },
      ),
    );
  }
  void initListItems() {
    listItems = [
      new _ListItem(
          bgName: 'assets/images/soso_growth.jpg',
          name: customcintroller.text.toString().isEmpty == false ? customcintroller.text.toString() : "Рост",
          detail: "Нажми, чтобы добавить свой рост"),
      new _ListItem(
          bgName: 'assets/images/soso_weight.jpg',
          name: customcintroller.text.toString().isEmpty == false ? customcintroller.text.toString() :  "Вес",
          detail: "Нажми, чтобы добавить свой вес"),
      new _ListItem(
          bgName: 'assets/images/soso_chest.jpg',
          name: "Грудь",
          detail: "PRO-версия"),
      new _ListItem(
          bgName: 'assets/images/soso_shoulder.jpg',
          name: "Плечи",
          detail: "PRO-версия"),
      new _ListItem(
          bgName: 'assets/images/soso_biceps.jpg',
          name: "Бицепс",
          detail: "PRO-версия")

    ];
  }
}
class _ListItem extends StatelessWidget {
  _ListItem({this.bgName, this.name, this.detail});

  // final int index;
  final String bgName;
  final String name;
  final String detail;
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 180.0,
      margin: const EdgeInsets.symmetric(
        vertical: 1.0,
      ),
      child: new Stack(
        children: <Widget>[
          new Container(
            decoration: new BoxDecoration(
              image: new DecorationImage(
                  image: new AssetImage(bgName),
                  colorFilter: new ColorFilter.mode(
                      Colors.black.withOpacity(0.45), BlendMode.darken),
                  fit: BoxFit.cover,
                  alignment: Alignment.center),
            ),
            child: new SizedBox.expand(
              child: Container(
                alignment: Alignment.center,
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    new Text(
                      name,
                      style: new TextStyle(fontSize: 29.0, color: Colors.white),
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 12.0),
                      child: new Text(
                        detail,
                        style:
                        new TextStyle(fontSize: 16.0, color: Colors.white),
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

我希望收到来自警报对话框的文本。

您要更新当前屏幕或另一个 Scaffold/screen 中的数据吗?第一个选项的解决方案是在 setState 中设置所需的数据或将其传递给模型(使用 ScopedModel)并更新视图。例如。 :

FlatButton(
              child: const Text('ОТМЕНА'),
              onPressed: () {
                setState(() {
                   myData = data;
                   Navigator.of(context).pop(); 
                  }); // not sure if this will work, could you try?
            }
            ),

如果它在 new/other 屏幕中,您可以在导航器中传递它,例如:

Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => NewScreen(data: myData),
          ),
        );
      },

这是否解决了您的问题?否则,请详细说明您需要什么。

如果您想更改列表中的某个项目,可以在调用 Navigator.pop() 之前使用 setState() 来完成。但是,无法通过 Navigator.pop() 传递数据,因为您可以使用 Navigator.push(... MyPage(data)).

你可以通过状态管理来实现你想要的。您可以检查一般的状态管理教程。但是我认为使用最多的两种实践是 Scoped Model 和 BLoC 模式。这些实践帮助您通过小部件树来回传递数据。我会推荐 BLoC 模式,有很多关于它的教程。还有一个包对 BLoC 模式非常有帮助:flutter_bloc.

我尝试在 AlertDialog 中使用 Navigator.of(context).pop("OK"); 但它不起作用。 使用 ValueChanged 作为 showDialog 方法的参数并且效果很好。

class Dialogs{
static showAlertDialog(BuildContext context, String title, String message,
      {List<String> actions, ValueChanged onChanged}) async {
    if (actions == null) {
      actions = ["OK"];//default OK button.
    }
    await showDialog(
      context: context,
      child: AlertDialog(
        title: Text(title ?? 'Message'),
        content: Text(message),
        actions: actions
            .map((e) => new FlatButton(
                child: Text(e.trim()),
                onPressed: () {
                  Navigator.of(context).pop(e.trim());
                  if (onChanged != null) {
                    onChanged(e.trim());
                  }
                }))
            .toList(),
      ),
    );
  }
}

来电者长得像

_onProcess(){
        String result = "";
        await Dialogs.showAlertDialog(context, "Warning", "Warning message", actions: ["OK", "Cancel"],
            onChanged: (value) {
          result = value;
        });
        if (result != "OK") {
          Dialogs.showSnackBarMessage(context, "Cancel This PTN");
          return;
        }
        ....process with the OK logic.

}