skip to Main Content

I have two screens, the first one fetches the data from the database and shows it on the screen. And the second screen creates a new user/course and sends it to the database. But when I use a pop to go back to the first screen, I want to update its data. How can I do this?

How can I update the screen data when returning from the second screen?

First Screen:

 class CourseList extends StatefulWidget {
  const CourseList({super.key});

  @override
  State<CourseList> createState() => _CourseListState();
}

class _CourseListState extends State<CourseList> {
  Future<List<Course>?> listCourses = Future.value([]);
  @override
  initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      setState(() {
        var course = CoursesData();
        listCourses = course.getCourses();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    var futureBuilder = FutureBuilder(
        future: listCourses,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            return createScreen(context, snapshot);
          } else if (snapshot.hasError) {
            return Text("${snapshot.error}");
          }
          return const Center(child: CircularProgressIndicator());
        });

    return futureBuilder;
  }

 Widget createScreen(BuildContext context, AsyncSnapshot snapshot) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  Navigator.of(context)
                      .pushNamed('/courseForm', arguments: null);
                },
                child: const Text("Adicionar Curso"))
          ],
        ),
        Expanded(
            child: ListView.builder(
          shrinkWrap: true,
          itemCount: snapshot.data.length,
          itemBuilder: ((context, index) {
            return CourseTile(snapshot.data[index]);
          }),
        ))
      ],
    );
  }
}

Second screen:

IconButton(
              onPressed: () {
                final isValid = _fomr.currentState!.validate();

                Navigator.pop(context, true);
                
              },
              icon: const Icon(Icons.save))

EDITED:

ElevatedButton(
                onPressed: () async {
                  var result = await Navigator.of(context)
                      .pushNamed('/courseForm', arguments: null);

                  if (result != null) {
                    setState(() {
                      var course = CoursesData();
                      listCourses = course.getCourses();
                    });
                  }
                  
                },
                child: const Text("Adicionar Curso"))

enter image description here

enter image description here

2

Answers


  1. You can navigate to second screen like this:

    var result = await Navigator.of(context).push(MaterialPageRoute(builder: (context) => SecondScreen()));
    
    if(result != null && result){
       setState(() {
            var course = CoursesData();
            listCourses = course.getCourses();
       });
    }
    

    then in your second screen when you pop like this

    Navigator.pop(context, true);
    

    as you are doing right now you pass back a bool variable to first screen which act like a flag and with that you can find when it is the time to reload the data. Also don forgot to await for the Navigator because of that you can receive the data from your second screen. Now when you come back from second screen, its going to update the ui.

    Login or Signup to reply.
  2. The documentation covers this example in detail. So I’ll paste in the relevant part:

    Future<void> _navigateAndDisplaySelection(BuildContext context) async {
      // Navigator.push returns a Future that completes after calling
      // Navigator.pop on the Selection Screen.
      final result = await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const SelectionScreen()),
      );
    

    The key is in this line:

      final result = await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const SelectionScreen()),
      );
    

    The result of navigator.push will be stored in result.

    So in your case, you should do this after getting the result (as @eamirho3ein has answered first, so I’m explaining) :

     setState(() {
            var course = CoursesData();
            listCourses = course.getCourses();
       });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search