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),
),
),
],
),
],
),
),
],
),
),
)
],
),
);
}
}
You could save the TextFormField value to a provider property, this way it will be available on all screens
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
User contributions licensed under CC BY-SA 3.0