【发布时间】:2020-04-16 09:34:42
【问题描述】:
我有一个带有导航抽屉菜单的应用程序。当我单击抽屉中的菜单项时,它会将我带到另一个页面。在那个屏幕上,我单击了另一个按钮,将我带到另一个屏幕。在这个屏幕上,我正在使用博客,但由于某种原因,我得到“getter bloc was called on null”。
这是我的代码 main.dart
import 'package:flutter/material.dart';
import 'package:finsec/widget/drawer_widget.dart';
import 'package:finsec/widget/inherited_month_year.dart';
import 'package:finsec/model/income/complexloginform.dart';
import 'package:finsec/screens/home/home_screen.dart';
import 'package:finsec/screens/transaction/transaction_list.dart';
import 'package:finsec/utils/colors.dart';
import 'package:finsec/utils/strings.dart';
import 'package:month_picker_dialog/month_picker_dialog.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:finsec/utils/localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:finsec/model/month_year.dart';
import 'package:finsec/data/blocs/provider.dart';
void main() => runApp(new MyApp( initialDate: DateTime.now()));
class MyApp extends StatefulWidget {
final String title = home;
final DateTime initialDate;
const MyApp({Key key, @required this.initialDate}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
DateTime selectedDate, prevSelectedDate;
String monthName1;
int monthNumber, year;
MonthYear monthYear;
getDrawerItemWidget(int pos, String title) {
switch (pos) {
case 0:
return new HomeScreen ();
case 1:
return new ComplexLoginForm();//SecondFragment();
case 2:
return new TransactionList(
outstanding: totalOutstanding,
received_or_paid:
totalReceived, transactionType: title,);
case 3:
return new TransactionList(
outstanding: totalOutstanding,
received_or_paid: totalPaid,
transactionType: title,);
default:
return new Text("Error");
}
}
String titleAppBar = home;
int tabIndex = 0;
double elevation = 0;
@override
void initState() {
setState(() {
titleAppBar = widget.title;
});
super.initState();
selectedDate = widget.initialDate;
}
void getMonthYear() {
if(selectedDate != null) {
monthName1 = monthNamesAbbrv[selectedDate.month];
monthNumber = selectedDate.month;
year = selectedDate.year;
prevSelectedDate = selectedDate;
}
else {
monthName1 = monthNamesAbbrv[prevSelectedDate.month];
monthNumber = prevSelectedDate.month;
year = prevSelectedDate.year;
}
monthYear = new MonthYear(monthNumber: monthNumber, year: year) ;
}
Widget homeScreen(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(titleAppBar),
elevation: elevation,
backgroundColor: colorPrimary,
actions: <Widget>[
Builder(
builder: (context) => FlatButton.icon(
icon: Icon(Icons.calendar_today, color: white,), //`Icon` to display
label: Text(monthName1 + ' $year' , style: TextStyle(color: white, fontSize: 18)), //`Text` to display
onPressed: () {
showMonthPicker(
context: context,
firstDate: DateTime( DateTime.now().year - 1 , 5),
lastDate: DateTime( DateTime.now().year + 1, 9 ),
initialDate: selectedDate ?? widget.initialDate
)
.then((date) => setState(() {
selectedDate = date ;//!= null ? date : prevSelectedDate;
}));
},
),
)
],
),
drawer: DrawerWidget((title, index) {
setState(() {
titleAppBar = title;
tabIndex = index;
});
}, tabIndex),
body: getDrawerItemWidget(tabIndex, titleAppBar),
);
}
@override
Widget build(BuildContext context) {
return
Provider(
child: MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('en'),
Locale('zh'),
Locale('fr'),
Locale('es'),
Locale('de'),
Locale('ru'),
Locale('ja'),
Locale('ar'),
Locale('fa'),
],
title: widget.title,
home: homeScreen(context)
);
}
}
事务列表类。这是我点击的菜单项,将我带到另一个屏幕
import 'package:flutter/material.dart';
import 'package:finsec/utils/colors.dart';
import 'package:finsec/utils/strings.dart';
import 'package:finsec/screens/transaction/text_switch_app_bar.dart';
import 'package:finsec/screens/transaction/row_column_layout_attributes.dart';
import 'package:finsec/widget/transaction_list_view.dart';
import 'package:finsec/screens/income/second_fragment.dart';
import 'package:finsec/screens/income/add_edit_income.dart';
import 'package:finsec/data/blocs/bloc_provider.dart';
import 'package:finsec/data/blocs/transaction_bloc.dart';
import 'package:finsec/model/income/income.dart';
import 'package:finsec/model/income/income_dao.dart';
import 'package:finsec/model/income/income_transactions.dart';
class TransactionList extends StatefulWidget {
TransactionList({
Key key,
this.outstanding,
this.received_or_paid,
this.transactionType
}) : super(key: key);
final String outstanding , received_or_paid, transactionType;
@override
_TransactionListState createState() => new _TransactionListState();
}
class _TransactionListState extends State<TransactionList> {
bool _isRow = true;
MainAxisAlignment _mainAxisAlignment = MainAxisAlignment.start;
CrossAxisAlignment _crossAxisAlignment = CrossAxisAlignment.start;
MainAxisSize _mainAxisSize = MainAxisSize.min;
String outstanding , received_or_paid, transactionType;
IncomeDao incomeDao;
List<Income> incomeList;
void _updateLayout(int index) {
setState(() {
_isRow = index == 0;
});
}
getTransactionType() {
switch ("${widget.transactionType}") {
case incomeTransaction:
return new AddEditIncome (appBarTitle: incomeTitle);
case expenseTransaction:
return new SecondFragment();
default:
return new Text("Error");
}
}
MainAxisAlignment _mainAxisAlignmentFromIndex(int index) {
switch (index) {
case 0:
return MainAxisAlignment.start;
case 1:
return MainAxisAlignment.end;
case 2:
return MainAxisAlignment.center;
case 3:
return MainAxisAlignment.spaceBetween;
case 4:
return MainAxisAlignment.spaceAround;
case 5:
return MainAxisAlignment.spaceEvenly;
}
return MainAxisAlignment.start;
}
void _updateMainAxisAlignment(int index) {
setState(() {
_mainAxisAlignment = _mainAxisAlignmentFromIndex(index);
});
}
CrossAxisAlignment _crossAxisAlignmentFromIndex(int index) {
switch (index) {
case 0:
return CrossAxisAlignment.start;
case 1:
return CrossAxisAlignment.end;
case 2:
return CrossAxisAlignment.center;
case 3:
return CrossAxisAlignment.stretch;
case 4:
return CrossAxisAlignment.baseline;
}
return CrossAxisAlignment.start;
}
void _updateCrossAxisAlignment(int index) {
setState(() {
_crossAxisAlignment = _crossAxisAlignmentFromIndex(index);
});
}
void _updateMainAxisSize(int index) {
setState(() {
_mainAxisSize = index == 0 ? MainAxisSize.min : MainAxisSize.max;
});
}
Widget _buildLayoutAttributesPage() {
return RowColumnLayoutAttributes(
onUpdateLayout: _updateLayout,
onUpdateMainAxisAlignment: _updateMainAxisAlignment,
onUpdateCrossAxisAlignment: _updateCrossAxisAlignment,
onUpdateMainAxisSize: _updateMainAxisSize,
);
}
Widget buildContent() {
int count = 0;
if (incomeList == null) {
incomeList = List<Income>();
}
return Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 1,
child: Column(
children: <Widget>[
Text(
"${widget.outstanding}",
textAlign: TextAlign.center,
style: TextStyle( fontSize: 16.0)
),
Padding(
padding: EdgeInsets.all(3.0),
child: Text(zeroAmount,
textAlign: TextAlign.center,
style: TextStyle(
color: green, fontSize: 16.0
)),
),
],
),
),
Container(width: 0.4, height: 40, color: Colors.black54),
Expanded(
flex: 1,
child: Column(
children: [
Text(
"${widget.received_or_paid}",
textAlign: TextAlign.center,
style: TextStyle( fontSize: 16.0)
),
Padding(
padding: EdgeInsets.all(3.0),
child: Text(zeroAmount, textAlign: TextAlign.center,
style: TextStyle(color: green, fontSize: 16)),
),
],
),
),
],
),
Padding(
padding: EdgeInsets.only(top: 12.0, left: 15.0, right: 15.0),
child: Divider(
height: 1,
color: Colors.black54,
),
),
Expanded(
flex: 1,
child: IncomeTransaction(),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TextSwitchAppBar(
bottom: PreferredSize(
child: _buildLayoutAttributesPage(),
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: colorPrimary,
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => getTransactionType()));
},
child: Icon(
Icons.add,
),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: buildContent()//IncomeTransaction()
),
);
}
}
在 TransactionList 类中,我单击一个按钮,将我带到另一个屏幕:AddEditIncome 在那个屏幕上,我正在调用一个块,例如:final bloc = Provider.of(context);
提供者的类是
import 'package:flutter/material.dart';
import 'bloc.dart';
class Provider extends InheritedWidget {
final bloc = Bloc();
Provider({Key key, Widget child}) : super(key: key, child: child);
bool updateShouldNotify(_) => true;
static Bloc of(BuildContext context) {
//* What it does is through the "of" function, it looks through the context of a widget from the deepest in the widget tree
//* and it keeps travelling up to each widget's parent's context until it finds a "Provider" widget
//* and performs the type conversion to Provider through "as Provider" and then access the Provider's bloc instance variable
return (context.dependOnInheritedWidgetOfExactType() as Provider).bloc;
}
}
我收到错误消息:“getter bloc 被调用为 null”。我在主屏幕的材料应用程序功能中指定了 Provider 类包装。但看起来这可能只对 home: homeScreen(context) 而不是导航抽屉中的菜单项。有人可以帮助解决此问题,以便当我单击任何导航菜单项时,我不会因为空错误而调用 bloc?提前致谢
【问题讨论】:
标签: flutter