【问题标题】:Provider not displaying updated state in another screen usng change notifier provider提供者未使用更改通知提供者在另一个屏幕中显示更新状态
【发布时间】:2021-01-14 10:02:13
【问题描述】:

我使用提供者和更改通知程序,问题是当我在同一个文件中更改状态并通知侦听器时,用户界面会更新,但是当我尝试从另一个屏幕中的模型访问相同的数据时,它仍然保留原始版本或第一个版本而不是更新版本,另一个文件中的类甚至使用更改通知提供者和消费者,就像内部带有模态类的文件一样,但没有更改值,它只保留初始值,第二个文件只有 changenotifierprovider 和 consumer,但它只显示初始的不是更新的而是第一个带有模型类的文件,并且 change notifier 函数在其小部件中显示更新的版本

这是我的第二个屏幕,即使在第一个屏幕中更新后也只显示初始状态

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,
                              ),
                            ),
                          ),
                        )
                      ]),
                )))));
  }
}

这是我第一次创建 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();





   }

【问题讨论】:

    标签: android flutter dart


    【解决方案1】:

    在您使用的第二个屏幕中

    ChangeNotifierProvider<MyModel>(
       create: (context) => MyModel(),
       ....
    )
    

    这意味着您实际上是在创建一个新模型,而不是重用您的第一页(它们不相关,更改一个不会改变另一个),我不知道您如何调用第二个屏幕所以这更具推测性,但是您可以将模型从前一个屏幕传递到第二个屏幕,然后使用ChangeNotifierProvider&lt;MyModel&gt;.value(),这将注册相同的模型并在发生更改时通知两个页面

    在第一屏

    onTap: Navigator.of(context).push(
        MaterialPageRoute(
          builder: BookScreen(Provider.of<MyModel>(context, listen: false))
        )
    );
    

    现在在第二个屏幕

    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,
            ....
        )
    

    显然,如果您在应用程序的开头(在您的第一个 MaterialApp 之上)创建了提供程序 MyModel,您就不需要所有这些逻辑,并且可以简单地在任何地方使用它

    【讨论】:

      猜你喜欢
      • 2021-01-14
      • 1970-01-01
      • 2021-08-11
      • 2011-11-19
      • 2021-07-30
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多