Home > database >  Passing variables from Tab to DefaultTabController - Flutter
Passing variables from Tab to DefaultTabController - Flutter

Time:01-30

I have a DefaultTabController with two pages nested in a scaffold. In my scaffold's App Bar is a save button and I want this button to return a value to a previous page, based on a variable that is calculated in one of the tabs. How do I get this value?

Here is my DefaultTabController

DefaultTabController(
    initialIndex: index,
    length: 2,
    child: Scaffold(
      backgroundColor: Theme.of(context).scaffoldBackgroundColor,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: fumigruen_accent,
        leading: CloseButton(
          color: Colors.black,
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
        actions: buildEditingActions(),
      ),
      body: Column(children: [
        tabBar(),
        Expanded(
          child: TabBarView(children: [
            //1st Tab
            GewichtsrechnerEinfach(),
            //2nd Tab
            Column()
          ]),
        )
      ]),
    ));}

And here is the save-Button I want to use to pass a varaible to the previous screen

  List<Widget> buildEditingActions() => [
    ElevatedButton.icon(
        style: ElevatedButton.styleFrom(
          backgroundColor: fumigruen_accent,
          elevation: 0,
          foregroundColor: Colors.black,
        ),
        onPressed: () {
          Navigator.of(context).pop(gewicht);
        },
        icon: Icon(Icons.save),
        label: Text("Speichern"))
  ];

The tabbar Code


  Widget tabBar() => TabBar(
          labelColor: Theme.of(context).primaryColor,
          indicatorColor: Theme.of(context).primaryColor,
          labelStyle: TextStyle(fontWeight: FontWeight.bold),
          tabs: [
            Tab(
              child: Row(mainAxisSize: MainAxisSize.min, children: [
                Icon(
                  Icons.assessment_outlined,
                ),
                SizedBox(
                  width: 5,
                ),
                Text("Einfach")
              ]),
            ),
            Tab(
              child: Row(mainAxisSize: MainAxisSize.min, children: [
                Icon(
                  Icons.addchart,
                ),
                SizedBox(
                  width: 5,
                ),
                Text("Fortgeschritten")
              ]),
            ),
          ]);

and an extract of the GewichtsrechnerEinfach():


    class _GewichtsrechnerEinfachState extends State<GewichtsrechnerEinfach> {
  final _formKey = GlobalKey<FormState>();
  num koerperlaenge = 0;
  num brustumfang = 0;
  var _koerperlaengeControler = TextEditingController();
  var _brustumfangControler = TextEditingController();
  num gewicht = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: SingleChildScrollView(
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              //{two textinput fields setting the variables koerperlaenge and brustumfang are here}
          
              Center(
                child: Container(
                  width: MediaQuery.of(context).size.width * 0.8,
                  decoration: ThemeHelper().buttonBoxDecoration(context),
                  child: ElevatedButton(
                      style: ThemeHelper().buttonStyle(),
                      child: Padding(
                        padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                        child: Text(
                          "berechnen".toUpperCase(),
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.bold,
                            color: Colors.white,
                          ),
                        ),
                      ),
                      onPressed: () async {
                        if (_formKey.currentState!.validate()) {
                          setState(() {
                            gewicht = Gewichtskalkulator().einfach(
                                brustumfang.toDouble(),
                                koerperlaenge.toDouble());
                          });
                        }
                      }),
                ),
              ),
            
            ],
          ),
        ),
      ),
    );
  }

The variable "gewicht" is calculated and changed in the first tab "GewichtsrechnerEinfach". So how do I get the changed variable to this main screen so that I can use it while saving?

Screenshot

Thanks a lot :)

CodePudding user response:

As I found out by chatting in comments section, you are changing a value in a Page and you want to use it in another pages or screen, this is why you should use StateManagement something like Provider. As you said you need to change the gewicht variable and use it where ever you want.

step 1) please add provider: ^6.0.5 (or any version that is compatible) in your pubspec.yaml and call flutter pub get.

step 2) now you should create a provider class to make all the variables that you want to use everywhere, alive. please create a dart file named:

gewichtsrechner_einfach_provider.dart

step 3) now you should put these codes in you provider class:

import 'package:flutter/material.dart';

class GewichtsrechnerEinfachProvider extends ChangeNotifier{
  
   num _gewicht = 0;
   
   num get gewicht => _gewicht;
   
   void setGewicht(num newGewicht){
     _gewicht = newGewicht;
     notifyListeners();
   }

}

as you see _gewicht is private and you can use it alive entire your project.

step 4) you should add the provider to main.dart:

MultiProvider(
      providers: [
// you are adding your provider
        ListenableProvider.value(value: GewichtsrechnerEinfachProvider()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ...........
      ),
    );

step 5) now you should use its setter and getter of gewicht:

as you see in _GewichtsrechnerEinfachState you are setting the value and should do this by using Consumer:

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: SingleChildScrollView(
        child: Consumer<GewichtsrechnerEinfachProvider>(//note this
          builder: (context, gewichtsrechnerEinfachProvider ,child) {
            return Form(
              key: _formKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  //{two textinput fields setting the variables koerperlaenge and brustumfang are here}

                  Center(
                    child: Container(
                      width: MediaQuery.of(context).size.width * 0.8,
                      decoration: ThemeHelper().buttonBoxDecoration(context),
                      child: ElevatedButton(
                          style: ThemeHelper().buttonStyle(),
                          child: Padding(
                            padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                            child: Text(
                              "berechnen".toUpperCase(),
                              style: TextStyle(
                                fontSize: 20,
                                fontWeight: FontWeight.bold,
                                color: Colors.white,
                              ),
                            ),
                          ),
                          onPressed: () async {
                            if (_formKey.currentState!.validate()) {
                              // and note this
                              gewichtsrechnerEinfachProvider.setGewicht(
                                  Gewichtskalkulator().einfach(
                                      brustumfang.toDouble(),
                                      koerperlaenge.toDouble())
                              );
                            }
                          }),
                    ),
                  ),

                ],
              ),
            );
          }
        ),
      ),
    );
  }

step 6) now you should use its getter where ever you want:

List<Widget> buildEditingActions() => [
  Consumer<GewichtsrechnerEinfachProvider>(
    builder: (context, gewichtsrechnerEinfachProvider ,child) {
      return ElevatedButton.icon(
          style: ElevatedButton.styleFrom(
            backgroundColor: fumigruen_accent,
            elevation: 0,
            foregroundColor: Colors.black,
          ),
          onPressed: () {
            // Navigator.of(context).pop(gewicht);
            print('here is your result: 
      ${gewichtsrechnerEinfachProvider.gewicht}');
          },
          icon: Icon(Icons.save),
          label: Text("Speichern"));
    }
  )
];


note that you can use your provider where ever you want even with this code not just consumer:

    var gewichtsrechnerEinfachProvider = Provider.of<GewichtsrechnerEinfachProvider>(context,listen: false);

as you see by changing its value the provider notifies to where you are showing it.

Ich hoffe, ich konnte dir helfen ;)

happy coding my friend...

  • Related