【问题标题】:How to pass data from alertdialog to page in flutter?如何将数据从alertdialog传递到flutter页面?
【发布时间】:2019-12-09 07:18:10
【问题描述】:

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

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

我尝试使用带有导航路线的 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 获取文本。

【问题讨论】:

    标签: flutter flutter-alertdialog


    【解决方案1】:

    您要更新当前屏幕或另一个脚手架/屏幕中的数据吗?第一个选项的解决方案是在 setState 中设置您想要的数据或将其传递给模型(使用 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】:

      我尝试在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.
      
      }
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-02
          • 1970-01-01
          • 2021-12-04
          • 1970-01-01
          • 2020-10-15
          • 1970-01-01
          • 2018-06-13
          • 2020-11-20
          相关资源
          最近更新 更多