Navigate Flat Button to Another Screen from Bottom Navigation Bar Item current Index using Provider

0

I created a provider using the provider package that tells if an item on the BottomNavigationBar is pressed, so that the page displayed matches the item from the BottomNavigationBar on the body properties of the Scaffold. I've made a screen with TextFormField and FlatButton on the first BottomNavigationBar item. what I want to do is, I want to add all the data that has been entered in TextFromField to the third screen item from the BottomNavigationBar that I have created, and then display the third item page from the BottomNavigationBar that was added to the data through FlatButton on first screen. I have been searching for solutions to this problem for days, but I also haven't found the answer.

My provider for BottomNavigationBar

import 'package:flutter/material.dart';

class Index with ChangeNotifier {
  int _currentindex = 0;
  get currentindex => _currentindex;

  set currentindex(int index){
    _currentindex = index;
    notifyListeners();
  }
}

My Scaffold

import 'package:flutter/material.dart';
import 'package:kakeiboo/View/balance_screen.dart';
import 'package:kakeiboo/View/bignote_screen.dart';
import 'package:kakeiboo/View/daily_screen.dart';
import 'package:provider/provider.dart';
import 'package:kakeiboo/controller/notifier.dart';
import 'package:kakeiboo/constant.dart';

class BottomNavigate extends StatefulWidget {
  @override
  _BottomNavigateState createState() => _BottomNavigateState();
}

class _BottomNavigateState extends State<BottomNavigate> {
  var currentTab = [
    BigNotePage(),
    DailyExpensesPage(),
    BalancePage(),
  ];

  @override
  Widget build(BuildContext context) {
    var provider = Provider.of<Index>(context);
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: currentTab[provider.currentindex],
      bottomNavigationBar: BottomNavigationBar(
        onTap: (index) {
          provider.currentindex = index;
        },
        currentIndex: provider.currentindex,
        backgroundColor: Color(0xff2196f3),
        showUnselectedLabels: false,
        selectedItemColor: Color(0xffffffff),
        type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.book),
            title: Text(
              'Big Note',
              style: kBottomNavigateStyle,
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.receipt),
            title: Text(
              'Daily',
              style: kBottomNavigateStyle,
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.account_balance_wallet),
            title: Text(
              'Balance',
              style: kBottomNavigateStyle,
            ),
          ),
        ],
      ),
    );
  }
}

My First Screen

import 'package:flutter/material.dart';
import 'package:kakeiboo/View/balance_screen.dart';
import 'package:kakeiboo/constant.dart';
class BigNotePage extends StatefulWidget {
  @override
  _BigNotePageState createState() => _BigNotePageState();
}

class _BigNotePageState extends State<BigNotePage> {
  bool _validate = false;
  final _formKey = GlobalKey<FormState>();
  final _incomeController = TextEditingController();
  final _expensesController = TextEditingController();
  final _savingsController = TextEditingController();

  @override
  void dispose() {
    _incomeController.dispose();
    _expensesController.dispose();
    _savingsController.dispose();
    super.dispose();
  }

  void cek() {
    String income = _incomeController.text;
    String expenses = _expensesController.text;
    String savings = _savingsController.text;

    if (int.parse(income) >= int.parse(expenses) + int.parse(savings)) {
      _formKey.currentState.save();
      Navigator.push(context, MaterialPageRoute(builder: (context)=>BalancePage()));
    } else {
      setState(() {
        _validate = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: kPading,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TitlePage('Big Note'),
          Expanded(
            child: Form(
              key: _formKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TxtField(
                    controler: _incomeController,
                    label: 'Income',
                  ),
                  TxtField(
                    controler: _expensesController,
                    label: 'Expenses',
                    error: _validate
                        ? 'Expenses + Savings Are More Than Income'
                        : null,
                  ),
                  TxtField(
                    controler: _savingsController,
                    label: 'Savings',
                    error: _validate
                        ? 'Expenses + Savings Are More Than Income'
                        : null,
                  ),
                  Container(
                    padding: EdgeInsets.symmetric(vertical: 12.0),
                    child: FlatButton(
                      padding: EdgeInsets.symmetric(vertical: 14.0),
                      onPressed: cek,
                      child: Text(
                        'WRITE THAT',
                        style: TextStyle(letterSpacing: 1.25),
                      ),
                      color: Colors.yellow,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          Container(
            width: 250.0,
            child: Text(
              '*if you get another income for this mounth, input the income again.',
              style: TextStyle(fontSize: 12.0),
            ),
          ),
        ],
      ),
    );
  }
}

class TxtField extends StatelessWidget {
  TxtField({this.label, this.controler, this.error});

  final String label;
  final TextEditingController controler;
  final String error;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 12.0),
      child: TextFormField(
        controller: controler,
        keyboardType: TextInputType.numberWithOptions(decimal: true),
        decoration: InputDecoration(
          errorText: error,
          labelText: label,
          prefix: Container(
            padding: EdgeInsets.all(8.0),
            child: Text(
              'IDR',
              style:
                  TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ),
    );
  }
}

My Third Screen

import 'package:flutter/material.dart';
import 'package:kakeiboo/constant.dart';

class BalancePage extends StatefulWidget {
  @override
  _BalancePageState createState() => _BalancePageState();
}

class _BalancePageState extends State<BalancePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: kPading,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TitlePage('Balance'),
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(top: 24.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Container(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          'Savings',
                          style: TextStyle(fontSize: 24.0),
                        ),
                        Row(
                          textBaseline: TextBaseline.alphabetic,
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.baseline,
                          children: [
                            Text('IDR'),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                '5.000.000',
                                style: TextStyle(
                                    fontSize: 56.0, color: Colors.green),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                  Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10.0),
                    ),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          'Budget',
                          style: TextStyle(fontSize: 24.0),
                        ),
                        Row(
                          textBaseline: TextBaseline.alphabetic,
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.baseline,
                          children: [
                            Text('IDR'),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                '5.000.000',
                                style: TextStyle(
                                    fontSize: 56.0, color: Colors.red),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}

My First Screen Look My Third Screen Look

flutter
asked on Stack Overflow Jun 8, 2020 by Randu Pratama

2 Answers

0

You could save the TextFormField value to a provider property, this way it will be available on all screens

answered on Stack Overflow Jun 8, 2020 by marti-B
0

Because you're already using Provider I would suggest using a PageController instead of your class Index(), this is because it will do exactly the same but PageController has some other advantages (as controlling a PageView, and it's already there to avoid more boilerplate when changing page)

//Your Savings model
class MySavings{
  int savings = 0;
  int income = 0;
  int expenses = 0;

}

import 'package:flutter/material.dart';
import 'package:kakeiboo/View/balance_screen.dart';
import 'package:kakeiboo/View/bignote_screen.dart';
import 'package:kakeiboo/View/daily_screen.dart';
import 'package:provider/provider.dart';
import 'package:kakeiboo/controller/notifier.dart';
import 'package:kakeiboo/constant.dart';
//import your Savings model

class BottomNavigate extends StatefulWidget {
  @override
  _BottomNavigateState createState() => _BottomNavigateState();
}

class _BottomNavigateState extends State<BottomNavigate> {

PageController _pageController;

  @override
  void initState() {
    super.initState();
    _pageController = PageController();
  }

  @override
  void dispose(){
    super.dispose();
    _pageController?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var provider = Provider.of<Index>(context);

    return MultiProvider(
      providers: [
        ChangeNotifierProvider<PageController>.value(value: _pageController), //now the PageController can be seen as any other Provider
        Provider<MySavings>(create: (_) => MySavings())
      ],
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        body: PageView(
          controller: _pageController,
          physics: NeverScrollableScrollPhysics(), //So the user doesn't scroll and move only when you pressed the buttons
          children: <Widget>[
            BigNotePage(),
            DailyExpensesPage(),
            BalancePage(),
          ],
        ),
        bottomNavigationBar: MyBottomBar()
     )
   );
  }
}

class MyBottomBar extends StatlessWidget{

  @override
  Widget build(BuildContext context){
    final PageController pageController = Provider.of<PageController>(context, listen: false);
    final int index = context.select<PageController, int>((pageController) => pageController.hasClients ? pageController.page.round() : pageController.initialPage);// the index the pageController currently is (if there is no client attached it uses the initialPAge that defaults to index 0)
    return BottomNavigationBar(
            onTap: (index) {
              pageController.jumpToPage(index);
              //In case you want it animated uncomment the next line and comment jumpToPage()
              //pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.ease);
            },
            currentIndex: index,
            backgroundColor: Color(0xff2196f3),
            showUnselectedLabels: false,
            selectedItemColor: Color(0xffffffff),
            type: BottomNavigationBarType.fixed,
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.book),
                title: Text(
                  'Big Note',
                  style: kBottomNavigateStyle,
                ),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.receipt),
                title: Text(
                  'Daily',
                  style: kBottomNavigateStyle,
                ),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.account_balance_wallet),
                title: Text(
                  'Balance',
                  style: kBottomNavigateStyle,
                ),
              ),
            ],
          ),
         );
  }
}

Now in SCREEN 1

import 'package:flutter/material.dart';
import 'package:kakeiboo/View/balance_screen.dart';
import 'package:kakeiboo/constant.dart';
//import your Savings model

class BigNotePage extends StatefulWidget {
  @override
  _BigNotePageState createState() => _BigNotePageState();
}

class _BigNotePageState extends State<BigNotePage> {
  bool _validate = false;
  final _formKey = GlobalKey<FormState>();
  final _incomeController = TextEditingController();
  final _expensesController = TextEditingController();
  final _savingsController = TextEditingController();

  @override
  void dispose() {
    _incomeController.dispose();
    _expensesController.dispose();
    _savingsController.dispose();
    super.dispose();
  }

  void cek() {
    String income = _incomeController.text;
    String expenses = _expensesController.text;
    String savings = _savingsController.text;

    if (int.parse(income) >= int.parse(expenses) + int.parse(savings)) {
      final PageController pageController = Provider.of<PageController>(context, listen: false);
      final MySavings mySavings = Provider.of<MySavings>(context, listen: false);
      mySavings..income = int.parse(income)..expenses = int.parse(expenses)..savings= int.parse(savings);
      _formKey.currentState.save();
      pageController.jumpToPage(2); //Index 2 is BalancePage
      //In case you want it animated uncomment the next line and comment jumpToPage()
      //pageController.animateToPage(2, duration: const Duration(milliseconds: 300), curve: Curves.ease);
    } else {
      setState(() {
        _validate = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: kPading,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TitlePage('Big Note'),
          Expanded(
            child: Form(
              key: _formKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TxtField(
                    controler: _incomeController,
                    label: 'Income',
                  ),
                  TxtField(
                    controler: _expensesController,
                    label: 'Expenses',
                    error: _validate
                        ? 'Expenses + Savings Are More Than Income'
                        : null,
                  ),
                  TxtField(
                    controler: _savingsController,
                    label: 'Savings',
                    error: _validate
                        ? 'Expenses + Savings Are More Than Income'
                        : null,
                  ),
                  Container(
                    padding: EdgeInsets.symmetric(vertical: 12.0),
                    child: FlatButton(
                      padding: EdgeInsets.symmetric(vertical: 14.0),
                      onPressed: cek,
                      child: Text(
                        'WRITE THAT',
                        style: TextStyle(letterSpacing: 1.25),
                      ),
                      color: Colors.yellow,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          Container(
            width: 250.0,
            child: Text(
              '*if you get another income for this mounth, input the income again.',
              style: TextStyle(fontSize: 12.0),
            ),
          ),
        ],
      ),
    );
  }
}

class TxtField extends StatelessWidget {
  TxtField({this.label, this.controler, this.error});

  final String label;
  final TextEditingController controler;
  final String error;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 12.0),
      child: TextFormField(
        controller: controler,
        keyboardType: TextInputType.numberWithOptions(decimal: true),
        decoration: InputDecoration(
          errorText: error,
          labelText: label,
          prefix: Container(
            padding: EdgeInsets.all(8.0),
            child: Text(
              'IDR',
              style:
                  TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ),
    );
  }
}

And finally in SCREEEN 3 you just call

final MySavings mysavings = Provider.of<MySavings>(context, listen: false);

and use its values (savings, expenses and income) to display in each Text, do some math if you want or change its value (If you want to update as soon as you change them then make MySavings a ChangeNotifier).

If you dont't want to use PageView and stick with the Index class just check the logic and change all the PageController with your index provider and it should work the same

answered on Stack Overflow Jun 8, 2020 by EdwynZN

User contributions licensed under CC BY-SA 3.0