Home > Software design >  How to Passing Data from Navigator Pop to Previous Page Where The Data is Used in The Widget Inside
How to Passing Data from Navigator Pop to Previous Page Where The Data is Used in The Widget Inside

Time:03-16

As stated in the title. How to return data to the previous page where the data is used to list widgets.

I have read this article Flutter Back button with return data or other similar articles. The code works perfectly. But there is a problem if I want to use the data returned to the widget that is in the list.\

Note that I only want to update one ListWidget, I don't want to refresh the state of the entire HomePage like the solution in this article Flutter: Refresh on Navigator pop or go back.

Here is a simple code sample to represent the problem I'm facing.

(check on ListWidget Class and SecondPage Class below)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

HomePage class

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: ListView.builder(
          itemCount: 4,
          itemBuilder: (_, index){
            return ListWidget(number: index 1);
          },
        )
      ),
    );
  }
}

ListWidget Class

class ListWidget extends StatelessWidget{
  ListWidget({@required this.number});
  
  final int? number;
  String? statusOpen;
  
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () async {
        statusOpen = await Navigator.of(context, rootNavigator: true)
                .push(
                  MaterialPageRoute(
                    builder: (BuildContext context) => SecondPage(),
                  ),
                );
      },
      child: Container(
        margin: EdgeInsets.all(10),
        padding: EdgeInsets.all(20),
        color: Colors.amber,
        child: Text(statusOpen != null ? '$number $statusOpen' : '$number Unopened'),
        // 
        // I want to change the text here to 'has Opened' when the user returns from SecondPage
        //
      ),
    );
  }
}

SecondPage Class

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context, 'has Opened');
            // return 'has Opened' to await statusOpen variable
          },
          child: Text('Go Back'),
        ),
      ),
    );
  }
}

is there any solution to handle this?

CodePudding user response:

If you make your listWidget a stateful widget, then you can get the solution where you just need to call setState when you return to your previous screen. And in this way you will be only changing your single list element and not the full screen.

sample code: changing this line- class ListWidget extends StatefulWidget and adding these lines -

      onTap: () async {
        statusOpen = await Navigator.of(context, rootNavigator: true)
                .push(
                  MaterialPageRoute(
                    builder: (BuildContext context) => SecondPage(),
                  ),
                );
        setState(() {
      
        });
      },

CodePudding user response:

If you used the data in your listview just call setstate after Navigator.pop like below code

 onTap: () async {
            statusOpen = await Navigator.of(context, rootNavigator: true)
                    .push(
                      MaterialPageRoute(
                        builder: (BuildContext context) => SecondPage(),
                      ),
                    ).then((value) async {
              setState(() {});
           
            });
          }, 
  • Related