flutter - 使用提供程序从底部导航栏项目当前索引将平面按钮导航到另一个屏幕
问题描述
我创建了一个provider
使用 来provider package
判断BottomNavigationBar
是否按下了 的项目,以便显示的页面与BottomNavigationBar
的 body 属性中的项目匹配Scaffold
。我已经在第一个项目TextFormField
上制作了一个屏幕。我想要做的是,我想将所有已输入的数据添加到我创建的第三个屏幕项目中,然后在第一个屏幕上显示添加到数据中的第三个项目页面. 这几天我一直在寻找这个问题的解决方案,但我也没有找到答案。FlatButton
BottomNavigationBar
TextFromField
BottomNavigationBar
BottomNavigationBar
FlatButton
我的底部导航栏提供商
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),
),
),
],
),
],
),
),
],
),
),
)
],
),
);
}
}
解决方案
因为您已经在使用 Provider,我建议您使用 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),
),
),
),
),
);
}
}
最后在屏幕 3 中,您只需调用
final MySavings mysavings = Provider.of<MySavings>(context, listen: false);
并使用其值(储蓄、支出和收入)显示在每个文本中,如果您愿意,请进行一些数学运算或更改其值(如果您想在更改它们后立即更新,则将 MySavings 设置为 ChangeNotifier)。
如果您不想使用 PageView 并坚持使用 Index 类,只需检查逻辑并使用您的索引提供程序更改所有 PageController,它应该可以正常工作
推荐阅读
- ubuntu-20.04 - 错误:在 ubuntu 20.04 上的 imc 0 上禁用了 edac skx ecc
- pandas - 如何在 mac os 中使用 conda 更新 pandas 库?
- azure-devops - 如何在 azure 管道内部版本号中指定时间字符串的格式
- bpf - eBPF:插入一个新的内部映射到`BPF_MAP_TYPE_HASH_OF_MAPS`?
- python - 如何在python中将计算出的timedelta显示为时间
- wso2 - 如何将 JSON 或 SOAP 属性用于路径 URL 参数或查询参数 WSO2 Entrerprise Integrator
- qt - 将自定义控件移动到自己的文件中时出现 QML TypeError
- python - Python 列表中除 13 及其后的数字外的数字总和
- html - CSS相对响应高度
- flutter - Flutter gridview 赔率 - 最后一个单元格占据行的完整宽度