Flutter 颤振:当我热重新加载我的提供者时,创建新对象
这是我的第一个问题,如果我犯了错误,我很抱歉。 关于我的问题,我发现了一些类似的问题,但没有一个能真正解决我的问题 所以我在我的项目中使用了Provider4.0.2,当我使用我的应用程序导航时,它可以正常工作,但是当我尝试热重新加载时,我的Provider会丢失状态,我的对象会重新开始 我就是这样实施的: main.dartFlutter 颤振:当我热重新加载我的提供者时,创建新对象,flutter,dart,Flutter,Dart,这是我的第一个问题,如果我犯了错误,我很抱歉。 关于我的问题,我发现了一些类似的问题,但没有一个能真正解决我的问题 所以我在我的项目中使用了Provider4.0.2,当我使用我的应用程序导航时,它可以正常工作,但是当我尝试热重新加载时,我的Provider会丢失状态,我的对象会重新开始 我就是这样实施的: main.dart void main() { Provider.debugCheckInvalidValueType = null; runApp( MultiProvid
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ExpenseDAO>(create: (context) => ExpenseDAO()),
ChangeNotifierProxyProvider<ExpenseDAO, ExpensesData>(
update: (context, dao, expensesData) => ExpensesData(dao: dao)),
ChangeNotifierProvider<User>(create: (context) => User()),
],
child: MyApp(),
),
);
}
class ExpensesData with ChangeNotifier {
ExpensesData({@required this.dao}) {
print('new object');
}
final List<Expense> _expenses = [];
final ExpenseDAO dao;
bool _isLoaded = false;
bool get isLoaded => _isLoaded;
UnmodifiableListView<Expense> get expenses => UnmodifiableListView(_expenses);
saveExpense(Expense expense) async {
await dao.insertExpense(expense);
await loadList(expense.userId);
notifyListeners();
}
loadList(String userId) async {
_expenses.clear();
_expenses.addAll(await dao.expenses(userId));
_isLoaded = true;
}
class ExpensesScreen extends StatefulWidget {
static const String id = 'expense_screen';
@override
_ExpensesScreenState createState() => _ExpensesScreenState();
}
class _ExpensesScreenState extends State<ExpensesScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kColorBackground,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'Expenses',
style: TextStyle(color: Colors.black),
),
),
body: Container(
child: Column(
children: <Widget>[
Center(
child: Consumer<ExpensesData>(
builder: (context, expensesData, child) {
return ListView.separated(
itemBuilder: (context, index) {
return Text(
'Tag = ${expensesData.expenses[index].category} '
'// Value = ${expensesData.expenses[index].value}');
},
separatorBuilder: (context, index) => Divider(),
itemCount: expensesData.expenses.length);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
size: 40,
),
onPressed: () {
Navigator.pushNamed(context, AddExpenseScreen.id);
},
),
);
}
}
void main(){
Provider.debugCheckInvalidValueType=null;
runApp(
多供应商(
供应商:[
ChangeNotifierProvider(创建:(上下文)=>ExpenseDAO()),
ChangeNotifierProxyProvider(
更新:(context,dao,expensesData)=>expensesData(dao:dao)),
ChangeNotifierProvider(创建:(上下文)=>User()),
],
子项:MyApp(),
),
);
}
费用数据。dart
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ExpenseDAO>(create: (context) => ExpenseDAO()),
ChangeNotifierProxyProvider<ExpenseDAO, ExpensesData>(
update: (context, dao, expensesData) => ExpensesData(dao: dao)),
ChangeNotifierProvider<User>(create: (context) => User()),
],
child: MyApp(),
),
);
}
class ExpensesData with ChangeNotifier {
ExpensesData({@required this.dao}) {
print('new object');
}
final List<Expense> _expenses = [];
final ExpenseDAO dao;
bool _isLoaded = false;
bool get isLoaded => _isLoaded;
UnmodifiableListView<Expense> get expenses => UnmodifiableListView(_expenses);
saveExpense(Expense expense) async {
await dao.insertExpense(expense);
await loadList(expense.userId);
notifyListeners();
}
loadList(String userId) async {
_expenses.clear();
_expenses.addAll(await dao.expenses(userId));
_isLoaded = true;
}
class ExpensesScreen extends StatefulWidget {
static const String id = 'expense_screen';
@override
_ExpensesScreenState createState() => _ExpensesScreenState();
}
class _ExpensesScreenState extends State<ExpensesScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kColorBackground,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'Expenses',
style: TextStyle(color: Colors.black),
),
),
body: Container(
child: Column(
children: <Widget>[
Center(
child: Consumer<ExpensesData>(
builder: (context, expensesData, child) {
return ListView.separated(
itemBuilder: (context, index) {
return Text(
'Tag = ${expensesData.expenses[index].category} '
'// Value = ${expensesData.expenses[index].value}');
},
separatorBuilder: (context, index) => Divider(),
itemCount: expensesData.expenses.length);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
size: 40,
),
onPressed: () {
Navigator.pushNamed(context, AddExpenseScreen.id);
},
),
);
}
}
class ExpensesData与ChangeNotifier{
ExpensesData({@required this.dao}){
打印(“新对象”);
}
最终清单_费用=[];
最终费用;
bool_isLoaded=false;
bool get isLoaded=>\u isLoaded;
UnmodifiableListView获取费用=>UnmodifiableListView(\u费用);
saveExpense(费用支出)异步{
等待道。插入费用(费用);
等待加载列表(expense.userId);
notifyListeners();
}
加载列表(字符串用户ID)异步{
_费用;
_expenses.addAll(等待dao.expenses(userId));
_isLoaded=true;
}
这就是我的问题所在。当热重新加载我得到一个新对象时,我可以通过在控制台中热重新加载时打印“new object”来看到这一点,之后费用列表为空,我的属性“isLoaded”返回为false
费用\u屏幕省道
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ExpenseDAO>(create: (context) => ExpenseDAO()),
ChangeNotifierProxyProvider<ExpenseDAO, ExpensesData>(
update: (context, dao, expensesData) => ExpensesData(dao: dao)),
ChangeNotifierProvider<User>(create: (context) => User()),
],
child: MyApp(),
),
);
}
class ExpensesData with ChangeNotifier {
ExpensesData({@required this.dao}) {
print('new object');
}
final List<Expense> _expenses = [];
final ExpenseDAO dao;
bool _isLoaded = false;
bool get isLoaded => _isLoaded;
UnmodifiableListView<Expense> get expenses => UnmodifiableListView(_expenses);
saveExpense(Expense expense) async {
await dao.insertExpense(expense);
await loadList(expense.userId);
notifyListeners();
}
loadList(String userId) async {
_expenses.clear();
_expenses.addAll(await dao.expenses(userId));
_isLoaded = true;
}
class ExpensesScreen extends StatefulWidget {
static const String id = 'expense_screen';
@override
_ExpensesScreenState createState() => _ExpensesScreenState();
}
class _ExpensesScreenState extends State<ExpensesScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kColorBackground,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'Expenses',
style: TextStyle(color: Colors.black),
),
),
body: Container(
child: Column(
children: <Widget>[
Center(
child: Consumer<ExpensesData>(
builder: (context, expensesData, child) {
return ListView.separated(
itemBuilder: (context, index) {
return Text(
'Tag = ${expensesData.expenses[index].category} '
'// Value = ${expensesData.expenses[index].value}');
},
separatorBuilder: (context, index) => Divider(),
itemCount: expensesData.expenses.length);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
size: 40,
),
onPressed: () {
Navigator.pushNamed(context, AddExpenseScreen.id);
},
),
);
}
}
class ExpenseScreen扩展StatefulWidget{
静态常量字符串id='expense_screen';
@凌驾
_ExpensesScreenState createState()=>\u ExpensesScreenState();
}
类别费用筛选状态扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:kColorBackground,
appBar:appBar(
背景颜色:Colors.white,
标题:正文(
"开支",,
样式:TextStyle(颜色:Colors.black),
),
),
主体:容器(
子:列(
儿童:[
居中(
儿童:消费者(
生成器:(上下文、费用数据、子项){
返回ListView.separated(
itemBuilder:(上下文,索引){
返回文本(
'Tag=${expensesData.expenses[index].category}'
'//Value=${expensesData.expenses[index.Value}');
},
separatorBuilder:(上下文,索引)=>Divider(),
项目计数:费用数据、费用、长度);
},
),
),
],
),
),
浮动操作按钮:浮动操作按钮(
子:图标(
Icons.add,
尺码:40,
),
已按下:(){
pushNamed(上下文,AddExpenseScreen.id);
},
),
);
}
}
你们能帮我吗?
我真的认为这是我的代码中的一个问题,但我不知道它是什么。阅读
ChangeNotifierProxyProvider
,它明确地说:
不要直接在更新中创建ChangeNotifier。
当使用的某个值更新时,这将导致您的状态丢失
您在以下方面违反了:
update:(context,dao,expensesData)=>expensesData(dao:dao)),
您应该将新的dao
对象注入先前创建的ExpensesData
对象,如(makedao
不再是final
):
update:(context,dao,expensesData)=>expensesData.dao=dao),
或
update:(context,dao,expensesData)=>expensesData.update(dao)),
这取决于您特定的代码和品味。很难理解您的问题是什么,特别是那些代码,请尝试用一个较小的示例重现它,并更好地解释不应该发生的事情。@mFeinstein下次在您回答关于我解决问题的文档后,我将尝试提出一个更好的问题。@mFeinsteinem,非常感谢!!天哪,我已经阅读了文档,没有发现我犯了什么错误,非常感谢!再次阅读您的答案和文档后,我发现我没有创建提供者,而是直接在更新中创建的!!再次感谢!!