Home > Blockchain >  flutter : value not passed to the previous screen and is shown null while using constructor
flutter : value not passed to the previous screen and is shown null while using constructor

Time:06-29

Basically, I have two classes Register and AddUser. I want to navigate value from the AddUser page to the RegisterPage but I am not getting any values despite using the constructor and getting null value while debugging. User First lands on the Register page where there is floatingAction button and it navigates to the AddUser Page. After providing the input , on clicking save button, it navigates back to the Register page where user will get the list of input.

**Register**

class Register extends StatefulWidget {
  late  String? names;
  Register({required this.names});


  @override
  _RegisterState createState() => _RegisterState(names);
}

class _RegisterState extends State<Register> {
  late String? names;

  _RegisterState(this.names);

 List<UserModel> getUserModel() {
  return [
    UserModel(

      name: widget.names??'',
    )
  ];
}

 // final user = UserSimplePreferences.getUser();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
     }

  @override
  Widget build(BuildContext context) {
    return   Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
        Padding(
        padding: const EdgeInsets.only(top: 10, bottom: 10),
    child: Text('Seleccione una categoría:',
    textAlign: TextAlign.center,
    style: TextStyle(color: Colors.black)
    ),
    ),
    Expanded(
    child: ListView.builder(
    itemCount: getUserModel().length,
    itemBuilder: (BuildContext ctx, int index) {
    return Container(
      margin: EdgeInsets.all(20),
      height: 150,
      child: Stack(
        children: [
          Text(getUserModel()[index].name)
        ],

     )


    );
    },
    ),
    ),
     FloatingActionButton(
        backgroundColor: Colors.indigo[900],
        onPressed: () {
          print(names);
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) {

              return AddUser(idUser: '',);

            }),
          );
        },
        child: Icon(Icons.add, color: Colors.white),
      ),
    ]
    );


  }
}



**AddUser**
class AddUser extends StatefulWidget {
  final String? idUser;

  const AddUser({required this.idUser});

  @override
  _AddUserState createState() => _AddUserState();
}

class _AddUserState extends State<AddUser> {
  final formKey = GlobalKey<FormState>();

  TextEditingController saaaaa = new TextEditingController();
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            automaticallyImplyLeading: false,
            title: Text(
              'Please Enter Your Details',
              textAlign: TextAlign.center,
            )),
        body: SafeArea(
          child: ListView(
            padding: EdgeInsets.all(16),
            children: [
              buildName(),
              const SizedBox(height: 12),
                          ],
          ),
        ),
      );

  Widget buildName() => buildTitle(
        title: 'Name',
        child: TextFormField(
          controller: saaaaa,
          //initialValue: name,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            hintText: 'Your Name',
          ),
          onChanged: (namer) => setState(() => namer = saaaaa.text),
        ),
      );

  

  Widget buildButton() => ButtonWidget(
      text: 'Save',

      onClicked: () async {
        
        setState(() async {
             Register(names : saaaaa.text );
             Navigator.pop(context);


        });
      });

  Widget buildTitle({
    required String title,
    required Widget child,
  }) =>
      Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text(
            title,
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          ),
          const SizedBox(height: 8),
          child,
        ],
      );
}

CodePudding user response:

You can achive this things by then callback in navigator and pass your value when you pop add screen. Please replace your code with below code

Register

class Register extends StatefulWidget {
  @override
  _RegisterState createState() => _RegisterState();
}


class _RegisterState extends State<Register> {
  List<UserModel> userList = [];

  // final user = UserSimplePreferences.getUser();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
      Padding(
        padding: const EdgeInsets.only(top: 10, bottom: 10),
        child: Text('Seleccione una categoría:',
            textAlign: TextAlign.center, style: TextStyle(color: Colors.black)),
      ),
      Expanded(
        child: ListView.builder(
          itemCount: userList.length,
          itemBuilder: (BuildContext ctx, int index) {
            return Container(
                margin: EdgeInsets.all(20),
                height: 150,
                child: Stack(
                  children: [Text(userList[index].name)],
                ));
          },
        ),
      ),
      FloatingActionButton(
        backgroundColor: Colors.indigo[900],
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) {
              return AddUser(
                idUser: '',
              );
            }),
          ).then((value) {
            if (value != null) {
              userList.add(UserModel(name: value));
              setState(() {});
            }
          });
        },
        child: Icon(Icons.add, color: Colors.white),
      ),
    ]);
  }
}



**AddUser**
class AddUser extends StatefulWidget {
  final String? idUser;

  const AddUser({required this.idUser});

  @override
  _AddUserState createState() => _AddUserState();
}

class _AddUserState extends State<AddUser> {
  final formKey = GlobalKey<FormState>();

  TextEditingController saaaaa = new TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            automaticallyImplyLeading: false,
            title: Text(
              'Please Enter Your Details',
              textAlign: TextAlign.center,
            )),
        body: SafeArea(
          child: ListView(
            padding: EdgeInsets.all(16),
            children: [
              buildName(),
              buildButton(),
              const SizedBox(height: 12),
            ],
          ),
        ),
      );

  Widget buildName() => buildTitle(
        title: 'Name',
        child: TextFormField(
          controller: saaaaa,
          //initialValue: name,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            hintText: 'Your Name',
          ),
          onChanged: (namer) => setState(() => namer = saaaaa.text),
        ),
      );

  Widget buildButton() => ButtonWidget(
      text: 'Save',
      onClicked: () async {
        setState(() async {
//          Register(names : saaaaa.text );
          Navigator.pop(context, saaaaa.text);
        });
      });

  Widget buildTitle({
    required String title,
    required Widget child,
  }) =>
      Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text(
            title,
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          ),
          const SizedBox(height: 8),
          child,
        ],
      );
}

CodePudding user response:

This may help and work for you

Register screen

FloatingActionButton(
    backgroundColor: Colors.indigo[900],
    onPressed: () async {
      print(names);
      var result = await Navigator.push(
          context,
          MaterialPageRoute(
            builder: (BuildContext context) => AddUser(idUser: '')));
      print(result);
      names = result;
      setState((){});
    },
    child: const Icon(Icons.add, color: Colors.white),
  )

Add screen

Widget buildButton() => MaterialButton(
  child: Text('Save'),
  onPressed: () {
      Navigator.pop(context, saaaaa.text);
});

I guess here after you can take and store in list in register page and then list down the names

CodePudding user response:

You can achieve this thing by using a callback function

add Callback function to your AddUser class and on save button just call your call back function like below:

class AddUser extends StatefulWidget {
  final String? idUser;
  // add this to your register class
  final Function(String) addedUser;


  const AddUser({required this.idUser,required this.addedUser});

  @override
  _AddUserState createState() => _AddUserState();
}

class _AddUserState extends State<AddUser> {
  final formKey = GlobalKey<FormState>();

  TextEditingController saaaaa = new TextEditingController();
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            automaticallyImplyLeading: false,
            title: Text(
              'Please Enter Your Details',
              textAlign: TextAlign.center,
            )),
        body: SafeArea(
          child: ListView(
            padding: EdgeInsets.all(16),
            children: [
              buildName(),
              const SizedBox(height: 12),
           ],
          ),
        ),
      );
  Widget buildButton() => ButtonWidget(
      text: 'Save',
      onClicked: () async {
        setState(() async {
            /// Just call addedUser like this
            widget.addedUser(saaaaa.text);
             Navigator.pop(context);
        });
      });
}

Simply where you are calling AddUser in Register Screen, add addedUser in the constructor of AddUser

import 'package:flutter/material.dart';

    class Register extends StatefulWidget {
      late  String? names;
      Register({required this.names});      
      @override
      _RegisterState createState() => _RegisterState(names);
    }
    
    class _RegisterState extends State<Register> {
      late String? names;
    
      _RegisterState(this.names);

      @override
      Widget build(BuildContext context) {
      
         FloatingActionButton(
            backgroundColor: Colors.indigo[900],
            onPressed: () {
              
              Navigator.push(
                context,
                MaterialPageRoute(builder: (_) {
              //just add parameter to your AddUser constructor
                return AddUser(idUser: '',addedUser:(value){
                    ///In this value variable you get the value of user you added on addUser page///
                    print(value);

                  });
                }),
              );
            },
            child: Icon(Icons.add, color: Colors.white),
          ),
        ]
        );
      }
    }
  • Related