mobdevkun
mobdevkun

Reputation: 463

How to pass data from alertdialog to page in flutter?

I am passing data from my alertdialog to item of listview.

Where I can find information about it?

I tried use TextEditingController, with Navigation Routes. And I used materials from this Tutorial

This is my code:

    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),
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

I expect to get text from alertdialog.

Upvotes: 1

Views: 8699

Answers (3)

Quang Duong
Quang Duong

Reputation: 11

I tried to use Navigator.of(context).pop("OK"); in the AlertDialog but it doesn't work. use ValueChanged as a param on the showDialog method and it works well.

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

the caller looks like

_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.

}

Upvotes: 1

SoF
SoF

Reputation: 39

If you want to change an item of the list you can do that with setState() before calling Navigator.pop(). It is not possible to pass data through Navigator.pop() though, as you may be able to do with Navigator.push(... MyPage(data)).

You could achieve what you want through State management. You can check for state management tutorials in general. But the two practices that are used most in my opinion are Scoped Model and BLoC pattern. These practices help you pass data through the widget tree back and forward. I would recommend BLoC pattern there are many tutorials about it. Also there is a package which can be very helpful with BLoC pattern: flutter_bloc.

Upvotes: -1

R. Flierman
R. Flierman

Reputation: 109

Do you want to update data in your current screen or in another Scaffold/screen? Solution for the first option would be to set your desired data in a setState or pass it to a Model (with ScopedModel) and update the view. E.g. :

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

If it is in a new/other screen, you can pass it in the Navigator like for example:

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

Does this solve your problem? Otherwise, please elaborate on what it is you need.

Upvotes: 2

Related Questions