[英]Provider not displaying updated state in another screen usng change notifier provider
im using provider and change notifier, the problem is when i change the state and notifiy listeners in the same file the user interface is updated, but when i try to access the same data from the model in another screen it still keeps the original or first version and not the updated version, the class in the other file is even using change notifier provider and a consumer just as the file with the modal class inside but is not changing the value, its only keeping the initial value, the second file only has changenotifierprovider and consumer, but it only displays the initial not the updated but the first file with the model class, and change notifier function is displaying the updated version in its widgets我正在使用提供程序和更改通知程序,问题是当我在同一文件中更改状态和通知侦听器时,用户界面会更新,但是当我尝试从另一个屏幕中的模型访问相同数据时,它仍然保留原始数据或第一个版本而不是更新版本,另一个文件中的类甚至使用更改通知程序提供程序和消费者,就像里面有模态类的文件一样,但没有改变值,它只保留初始值,第二个文件只有changenotifierprovider 和 consumer,但它只显示初始而不是更新的文件,而是显示模型类的第一个文件,并且更改通知函数在其小部件中显示更新的版本
And this is my second screen, which only displays the intial states even after they are updated in the frst screen这是我的第二个屏幕,即使它们在第一个屏幕中更新,它也只显示初始状态
import 'package:flutter/material.dart';
import 'package:hotel_search/common/theme.dart';
import 'package:hotel_search/sliding_bottom_sheet_content.dart';
import 'package:hotel_search/home_page.dart';
import 'package:provider/provider.dart';
class BookScreen extends StatefulWidget {
@override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
@override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
@override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
elevation: 0,
titleSpacing: 0,
backgroundColor: Colors.white,
title: Text(' ',
style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 20,
))),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 40,
),
Container(
width: MediaQuery.of(context).size.width - 100,
height: 100,
child: Image.asset(
"assets/images/brand.png",
width: 0,
height: 0,
fit: BoxFit.cover,
)),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding:
EdgeInsets.only(left: 20, top: 20, bottom: 20),
width: MediaQuery.of(context).size.width,
child: Text('Review \nYour Booking',
style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 30,
))),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left: 20, top: 20),
width: MediaQuery.of(context).size.width,
child: Text("HOTEL NAME",
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20,
fontWeight: FontWeight.w700,
))),
Row(children: <Widget>[
Consumer<MyModel>(
builder: (context, myModel, children) {
return Container(
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text(
myModel.datesChosen.toString(),
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text(myModel.roomtype.toString(),
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)),
),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text("CHECK IN AND OUT TIME",
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text("TYPE OF ROOM CHOSEN",
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)))
]));
}),
Spacer(),
Container(
margin: EdgeInsets.only(right: 20),
width: 150,
height: 120,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("img/card.jpg"),
fit: BoxFit.cover),
color: Colors.grey[300],
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(
0, 3), // changes position of shadow
)
]))
]),
SizedBox(height: 60),
Divider(
height: 25,
color: Colors.grey[300],
),
SizedBox(height: 20),
Container(
color: Color(0xff008d4b),
height: 60,
width: MediaQuery.of(context).size.width - 50,
child: FlatButton(
onPressed: () {
/*...*/
},
child: Text(
"Book Now",
style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 20,
),
),
),
)
]),
)))));
}
}
this is the part of my first where i created my changenotifier, theres more but it was long so i just added this part, but all widgets here display the updated state这是我第一次创建 changenotifier 的部分,还有更多,但时间很长,所以我只添加了这部分,但这里的所有小部件都显示更新状态
class MyModel with ChangeNotifier{
String datesChosen = "Click here";
String checkin;
String checkout;
String email;
String name;
String roomtype = "Click here";
String phonenumber;
String hotelname;
void updateData1 (data){
datesChosen = data;
print(datesChosen);
notifyListeners();
}
void updateData2 (data){
roomtype = data;
print(roomtype);
notifyListeners();
}
in your second screen you're using在您使用的第二个屏幕中
ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
....
)
which means you're actually creating a new Model, not reusing the one of your first page (They're unrelated and changing one won't change the other), I don't know how you call the second screen so this is more speculative but you doul pass the model from the previous screen to the second and then use ChangeNotifierProvider<MyModel>.value()
, that will register the same model and notify both pages when a change occurs这意味着您实际上是在创建一个新模型,而不是重用第一页中的一个(它们不相关,更改一个不会更改另一个),我不知道您如何调用第二个屏幕,所以这更多推测性的,但您将模型从前一个屏幕传递到第二个屏幕,然后使用ChangeNotifierProvider<MyModel>.value()
,这将注册相同的模型并在发生更改时通知两个页面
in the first screen在第一个屏幕
onTap: Navigator.of(context).push(
MaterialPageRoute(
builder: BookScreen(Provider.of<MyModel>(context, listen: false))
)
);
now in the second screen现在在第二个屏幕
class BookScreen extends StatefulWidget {
final MyModel model;
BookScreen(this.model);
@override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
@override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
@override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>.value(
value: widget.model,
....
)
Obviously if you created the provider MyModel at the beginning of your app (above your first MaterialApp) you don't need all this logic and could simply use it everywhere显然,如果您在应用程序的开头(在您的第一个 MaterialApp 之上)创建了提供程序 MyModel,则您不需要所有这些逻辑,只需在任何地方使用它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.