使用提供程序将平面按钮从底部导航栏项目当前索引导航到另一个屏幕



我使用provider package创建了一个provider,该告诉是否按下了BottomNavigationBar上的项目,以便显示的页面与Scaffold正文属性上BottomNavigationBar中的项目相匹配。我已经制作了一个屏幕,在第一个BottomNavigationBar项目上TextFormFieldFlatButton。我想做的是,我想将TextFromField中输入的所有数据添加到我创建的BottomNavigationBar的第三个屏幕项目中,然后显示通过FlatButton添加到数据BottomNavigationBar中的第三个项目页面。 几天来我一直在寻找这个问题的解决方案,但我也没有找到答案。

我的底部导航栏提供程序

import 'package:flutter/material.dart';
class Index with ChangeNotifier {
int _currentindex = 0;
get currentindex => _currentindex;
set currentindex(int index){
_currentindex = index;
notifyListeners();
}
}

我的脚手架

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,
),
),
],
),
);
}
}

我的第一个屏幕

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),
),
),
),
),
);
}
}

我的第三个屏幕

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),
),
),
],
),
],
),
),
],
),
),
)
],
),
);
}
}

我的第一个屏幕外观 我的第三屏幕外观

因为你已经在使用提供程序,所以我建议使用PageController而不是你的类Index((,这是因为它会做完全相同的事情,但PageController还有其他一些优点(作为控制PageView,并且它已经存在以避免在更改页面时有更多的样板(

//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,
),
),
],
),
);
}
}

现在在屏幕 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),
),
),
),
),
);
}
}

最后在SCREEEN 3中,您只需致电

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

并使用其值(储蓄,支出和收入(显示在每个文本中,如果需要或更改其值,请进行一些数学运算(如果您想在更改它们后立即更新,请将MySavings 设置为更改通知程序(。

如果您不想使用PageView并坚持使用Index类,只需检查逻辑并使用索引提供程序更改所有PageController,它应该可以正常工作

您可以将 TextFormField 值保存到提供程序属性,这样它将在所有屏幕上可用

最新更新