如何将数据从Alertdialog传递到Flutter中的页面?

时间:2019-07-31 17:46:06

标签: flutter flutter-alertdialog

我正在将数据从我的alertdialog传递到listview的项目。

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

我尝试将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),
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

我希望从Alertdialog中获取文本。

3 个答案:

答案 0 :(得分:1)

我尝试在Navigator.of(context).pop("OK");中使用AlertDialog,但是它不起作用。 使用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.

}

答案 1 :(得分:0)

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

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

如果它在新屏幕或其他屏幕中,则可以在导航器中将其传递,例如:

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

这可以解决您的问题吗?否则,请详细说明您的需求。

答案 2 :(得分:0)

如果要更改列表的项目,可以在调用Navigator.pop()之前使用setState()进行操作。但是,无法通过Navigator.pop()传递数据,因为您可以使用Navigator.push(... MyPage(data))。

您可以通过状态管理来实现所需的目标。您通常可以检查状态管理教程。但是在我看来,最常用的两个实践是范围模型和BLoC模式。这些做法可帮助您前后通过小部件树传递数据。我建议BLoC模式有很多关于它的教程。还有一个可以对BLoC模式非常有用的软件包:flutter_bloc