user2895656
user2895656

Reputation: 57

Flutter pass data to new screen with onTap

My application has a bottom navigation bar, with 2 pages in the menu. On page 1, I can fill out a form and it calculates me values ​​that it displays to me by pushing in a 1.1 page. On this page I have a button that allows me to redirect me to page 2 as if I clicked menu 2 of the navigation bar.

This works. My problem is how to send the data from my page 1.1 to this page 2.

The goal being that my page 2 is a form which is empty if I call it by the navigation bar but which is filled automatically if I pass by the page 1.1 in focus of the calculated values.

Here an exemple of the redirection that I do:

enter image description here

Here is my code :

my_app.dart :

final ThemeData _AppTheme = AppTheme().data;
final navBarGlobalKey = GlobalKey(); // => This is my key for redirect page

class MyApp extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'App',
      home: MyBottomNavigationBar(),
      theme: _AppTheme,
      navigatorKey: locator<NavigationService>().navigatorKey,
      onGenerateRoute: Router.generateRoute,
      initialRoute: HOME_ROUTE,
    );
  }
}

My bottom_navigation_bar.dart :

class MyBottomNavigationBar extends StatefulWidget
{
  MyBottomNavigationBar({Key key}) : super(key: key);

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

class _MyBottomNavigationBarState extends State<MyBottomNavigationBar>
{
  int _pageIndex = 0;
  final List<Widget> _pagesOption = [
    page1.1(), // => Here I load direclty my page 1.1 with data for the exemple
    page2(),
  ];

  void onTappedBar(int index)
  {
    setState(() {
      _pageIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child : Scaffold(
          body : _pagesOption.elementAt(_pageIndex),
          bottomNavigationBar: BottomNavigationBar(
            key: navBarGlobalKey,
            currentIndex: _pageIndex,
            onTap: onTappedBar,
            type: BottomNavigationBarType.fixed,
            items : [
              BottomNavigationBarItem(
                  icon : Icon(Icons.home),
                  title : Text('Home')
              ),
              BottomNavigationBarItem(
                  icon : Icon(Icons.settings),
                  title : Text('Setting')
              ),
            ]
          ),
        )
    );
  }
}

And here my widget submit button of page 1.1 :

Widget _getSubmitButton(){
    return RaisedButton(
      child: Text(
        'Send'
      ),
      onPressed: () {
        final BottomNavigationBar navigationBar = navBarGlobalKey.currentWidget;
        navigationBar.onTap(1); // => How to send data that I have in my page ???
      },
    );
  }

Upvotes: 0

Views: 1088

Answers (3)

Alok
Alok

Reputation: 8978

For this, you can use Shared Preferences, the main idea is that:

  1. Store the value of the calculated value in SharedPref from Page 1 when you're passing to Page 1.1
  2. Let you checks for the value by default in Page 2's initState(), any changes in the Shared Preferences will be fetched in the Page 2 itself, using SharedPref get method.

WHY?

This is probably a cleaner way to achieve what you want, since in the BottomNavigationBar will not help you do this, but a Shared Preferences value will always give you that data which you can use it any time

Let's see how you can achieve this:

PAGE ONE

// Set the data of the form here
class _PageOneState extends State<PageOne>
{
   void onSubmit() async{
      SharedPreferences prefs = await SharedPreferences.getInstance();
      
      //make sure you store the calculated value, if that is String
      // use setString() or if it is an int, setInt()
      // and then pass it to the SharedPref
      // key is a string name, which is used to access 
      // key and store, so choose the name wisely
      await prefs.setInt("key", your_calculated_value);
   }
}

PAGE TWO

class _PageTwoState extends State<PageTwo>
{   
    Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
    // This will be responsible for getting the result from SharedPref
    int calculated_value;

    @override
    void initState(){
      super.initState();
      
      // get your list here
      calculated_value = _prefs.then((SharedPreferences prefs){
          // here if no data is then _values will have 0
          // which you can use it to check and populate data
          return (prefs.getInt("key") ?? 0);
      });
    }
}

This is the most reasonable way of doing the thing which you want. In this manner, whenever, PageTwo will trace any values, it will reflect, else, your choice for 0 check result. Let me know, if you have any doubts in that.

Upvotes: 1

iyasu
iyasu

Reputation: 1

You can pass the the values as arguments when you push to your new screen. This could get messy if you're building a larger project.

A cleaner implementation would be to use a Provider. Set up the data you want in a model mixed in with ChangeNotifier and use Provider.of<*name of your class*>(context) where ever you need to use it.

Upvotes: 0

Sagar
Sagar

Reputation: 83

In your FirstActivity

onPressed: () {
    navigatePush(SecondActivity(text: "Data"));
}

In your SecondActivity

class SecondActivity extends StatefulWidget {
    String text;
    
    SecondActivity({this.text});
}

Upvotes: 0

Related Questions