我遇到的情况是我有我的主类和一个继承小部件。当我将主类包装在继承类中并传递一个参数时,由于某种原因,继承类未保留我传递的参数的值。下面是我的代码
主班
import 'package:flutter/material.dart';
import 'package:finsec/widget/drawer_widget.dart';
import 'package:finsec/widget/inherited_month_year.dart';
import 'package:finsec/screens/income/second_fragment.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';
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 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: () {
// DateTime date = new DateTime.now();
// showMonthPicker(context: context, initialDate: date);
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) {
getMonthYear();
print('MONTH');
print(monthYear.monthNumber);
print('YEAR');
print(monthYear.year);
return StateContainer(
// monthNumber: monthNumber,
// year: year,
child: new 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)
),
monthYear: monthYear,
);
}
}
继承小部件类
import 'package:flutter/material.dart';
import 'package:finsec/model/month_year.dart';
class StateContainer extends StatefulWidget {
final Widget child;
final MonthYear monthYear;
StateContainer({@required this.child, this.monthYear});
static StateContainerState of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(InheritedMonthYear)
as InheritedMonthYear).data;
}
@override
StateContainerState createState() => new StateContainerState();
}
class StateContainerState extends State<StateContainer> {
MonthYear monthYear;// =new MonthYear(monthNumber: 4, year: 2012);
void updateMonthYear({month, year}) {
if (monthYear == null) {
monthYear = new MonthYear(monthNumber: month, year: year);
setState(() {
monthYear = monthYear;
});
} else {
setState(() {
monthYear.monthNumber = month ?? monthYear.monthNumber;
monthYear.year = year ?? monthYear.year;
});
}
}
@override
Widget build(BuildContext context) {
print('MONTH CONTAINER');
print(monthYear.monthNumber);
return InheritedMonthYear(
data: this,
child: widget.child,
);
}
}
class InheritedMonthYear extends InheritedWidget {
final StateContainerState data;
InheritedMonthYear({
Key key,
@required this.data,
@required Widget child,
}) : super(key: key, child: child);
static InheritedMonthYear of(BuildContext context) {
return context.inheritFromWidgetOfExactType(InheritedMonthYear) as InheritedMonthYear;
}
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
// bool updateShouldNotify(InheritedMonthYear old) {
//return monthNumber != old.monthNumber || year != old.year;
// }
}
在主类中,我在构建函数中调用getMonthYear()函数,该函数显示以下内容
I/flutter (23720): MONTH
I/flutter (23720): 10
I/flutter (23720): YEAR
I/flutter (23720): 2019
这些值存储在变量monthYear中,该变量从主类传递给StateContainer类。如果您在StateContainer类中注意到,则在生成函数im中打印我从main传递的值
@override
Widget build(BuildContext context) {
print('MONTH CONTAINER');
print(monthYear.monthNumber);
return InheritedMonthYear(
data: this,
child: widget.child,
);
}
但是,我收到错误消息
I/flutter (23720): MONTH CONTAINER
I/flutter (23720): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (23720): The following NoSuchMethodError was thrown building StateContainer(dirty, state:
I/flutter (23720): StateContainerState#e2af1):
I/flutter (23720): The getter 'monthNumber' was called on null.
I/flutter (23720): Receiver: null
I/flutter (23720): Tried calling: monthNumber
I/flutter (23720):
I/flutter (23720): User-created ancestor of the error-causing widget was:
I/flutter (23720): MyApp file:///C:/Users/rodrigue33/Documents/APP/finsec/lib/main.dart:15:27
I/flutter (23720):
I/flutter (23720): When the exception was thrown, this was the stack:
I/flutter (23720): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
I/flutter (23720): #1 StateContainerState.build (package:finsec/widget/inherited_month_year.dart:39:21)
当我尝试打印print(monthYear.monthNumber);看起来monthYear为空,并且抖动抛出错误。我不知道如果我从主类传递monthYear,并且在调用StateContainer类以验证monthYear不为null之前打印出这些值,怎么可能为null。有人可以告诉我我做错了什么吗?为什么当我将值(monthYear)传递给StateContainer时,值不保留,而是在StateContainer中使用monthYear为null?预先感谢