从一个屏幕跳到另一个屏幕时,如何不丢失列表中的数据?

问题描述

我有一个ViewTotalItemProvider类,它扩展了ChangeNotifier。在课程内部,有一个像这样的列表。

class ViewTotalItemProvider extends ChangeNotifier{
List<CartPlantLists> cartPlantList3 = [];
}

此外,还有3个屏幕,包括PlantFeatureScreen1ParticularPlant2CartDetais3之类的类。所有这些都是有状态的小部件,我将在第二个屏幕中添加一些项目,即ParticularPlant2类。

当我尝试在第二个屏幕和第三个屏幕中显示列表中的项目时,它起作用了。
但是,该值不会在firstScreen(即PlantFeatureScreen1)中更新。但是,当我重新加载应用程序时,它会显示更新后的值。
为什么会这样呢?我该怎么解决

代码
ViewTotalItemProvider

List<CartPlantLists> cartPlantList3 = [];

class ViewTotalItemProvider extends ChangeNotifier{

  addQuantity(index){
     cartPlantList3[index].qu++;
    notifyListeners();
  }

  subtrachQuantity(index){
    cartPlantList3[index].qu--;
    notifyListeners();

  }
}

firstScreen PlantFeatureScreen1在这里我要更新最后一个小部件中的值)

class PlantFeatureScreen1 extends StatefulWidget {
  @override
  _PlantFeatureScreen1State createState() => _PlantFeatureScreen1State();
}

class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {


  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ViewTotalItemProvider>(
      create: (context) => ViewTotalItemProvider(),child:Builder(builder: (context) {
        return           Column(
        children: <Widget>[
          TopAppBar(),Expanded(
            flex: 1,child: Align(
              alignment: Alignment(-1,0),child: Container(
                decoration: Boxdecoration(
                  color: Colors.white,),child: Text(
                  "Plants",style: TextStyle(fontSize: 30,fontWeight: FontWeight.w700),Expanded(
            flex: 5,child: Container(
              width: double.infinity,decoration: Boxdecoration(
                color: Colors.blue,child: DefaultTabController(
                length: 5,child: Column(
                  children: [
                    Container(
                      height: 50,width: double.infinity,child: TabBar(
                        isScrollable: true,tabs: ourAllLists.tabMaker(),Container(
                      height: 317,decoration: Boxdecoration(color: Colors.white),child: TabBarView(
                        children: ourAllLists.tabViewerMaker(context),],Padding(
            padding: const EdgeInsets.fromLTRB(20,20,20),child: Container(
              alignment: Alignment.bottomright,height: 120,child: Stack(
                overflow: Overflow.visible,children: [
                  Container(
                    height: 70,width: 105,decoration: Boxdecoration(
                        color: Color(0xFF96CA2D),borderRadius: BorderRadiusDirectional.horizontal(
                            end: Radius.circular(32),start: Radius.circular(32))),child: Icon(FontAwesomeIcons.shoppingBag,color:Colors.white,size:30),Positioned(
                    // top: 0,bottom: 50,right: 0,child: Consumer<ViewTotalItemProvider>(
                      builder: (context,value,child){
                        return Container(
                        height: 35,width: 35,decoration: Boxdecoration(
                          color: Colors.white,borderRadius: BorderRadius.circular(50),border: Border.all(color: Color(0xFF96CA2D),width: 4)
                        ),child: Center(child: Text(ourAllLists.totalquantity().toString(),style:TextStyle(fontSize: 20,color: Color(0xFF96CA2D)))),);
                      }),)
        ],);   
      })
 );
  }
}

secondScreen ParticularPlant2

class ParticularPlant2 extends StatefulWidget {
  final indexnumber;
  ParticularPlant2({@required this.indexnumber});

  @override
  _ParticularPlant2State createState() => _ParticularPlant2State();
}

class _ParticularPlant2State extends State<ParticularPlant2> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Scaffold(
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.start,children: [
              TopAppBar(),Container(
                decoration: Boxdecoration(
                  color: Colors.red,borderRadius: BorderRadiusDirectional.only(
                    bottomStart: Radius.circular(50),child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,children: [
                    Text(
                      ourAllLists
                          .mainListAllPlantDetailsList1[widget.indexnumber].pN,style: kPlantNameStyle,Text(
                      ourAllLists
                          .mainListAllPlantDetailsList1[widget.indexnumber].ca
                          .toupperCase(),style: TextStyle(
                        fontSize: 15,Text(
                      "\$" +
                          ourAllLists
                              .mainListAllPlantDetailsList1[widget.indexnumber]
                              .pr
                              .toString(),style: kItemPrice,SizedBox(height: 100),Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,children: [
                        Column(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
                            Container(
                              height: 80,width: 80,decoration: Boxdecoration(
                                  color: Colors.white,borderRadius: BorderRadius.circular(50)),child: Icon(
                                FontAwesomeIcons.flag,color: Color(0xFF9DCD3C),SizedBox(
                              height: 50,FlatButton(
                              onpressed: () {
                                final tile = cartPlantList3.firstWhere(
                                    (item) =>
                                        item.pN ==
                                        ourAllLists
                                            .mainListAllPlantDetailsList1[
                                                widget.indexnumber]
                                            .pN,orElse: () => null);
                                if (tile != null) {
                                } else {
                                  cartPlantList3.add(
                                    CartPlantLists(
                                      quantity: 1,plantName: ourAllLists
                                          .mainListAllPlantDetailsList1[
                                              widget.indexnumber]
                                          .pN,category: ourAllLists
                                          .mainListAllPlantDetailsList1[
                                              widget.indexnumber]
                                          .ca,price: ourAllLists
                                          .mainListAllPlantDetailsList1[
                                              widget.indexnumber]
                                          .pr,);
                                }
                                print(cartPlantList3.length);
                              },child: Container(
                                height: 80,decoration: Boxdecoration(
                                    color: Color(0xFF9DCD3C),color: Colors.white),)
                          ],Container(
                          height: 250,child: Image(image: Assetimage("assets/tulip.png")),)
                      ],)
                  ],)
            ],);
  }
}

解决方法

似乎您使用提供者的方式错误。在您的方案中,执行此操作的最佳方法是使用MultiProvider将MaterialApp包裹在main.dart文件中的MyApp()中。尝试如下操作:https://pub.dev/packages/provider#multiprovider您可以在其中放置一个ChangeNotifierProvider。

return MultiProvider(
  providers: [
    ChangeNotifierProvider<ViewTotalItemProvider>(
        create: (context) => ViewTotalItemProvider()),],child: MaterialApp(...)
);

此外,您还必须在模型中放置吸气剂和吸气剂。这是一个示例:

class ImageModel extends ChangeNotifier {
  String _base64Image;
  get base64Image => _base64Image;
  set base64Image(String base64Image) {
    _base64Image = base64Image;
    notifyListeners();
  }
}

我还建议您使用Selector代替Consumer(理想情况下,您应该使用Selector代替Consumer,这样才使小部件仅在其侦听的值发生更改时才重建)这是基于上述模型的示例:

@override
Widget build(BuildContext context) {
 //other widgets
 Selector<ImageModel,String>(
  selector: (_,model) => model.base64Image,builder: (_,image,__) {
   return Text(image);
     },);
  }
 )
}

以下是使用RaisedButton进行设置的方法:

class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {
  final itemModel;
  List<CartPlantLists> myList=[];
  @override
  Widget build(BuildContext context) {
    itemModel = Provider.of<ViewTotalItemProvider>(context,listen:false);
    print(itemModel.yourVariable); //getting the value
    return Container(
             child: RaisedButton(
               child:Text("Set Item");
               onPressed:(){
               itemModel.yourVariable=myList; //setting the value
               },),);
  }
 }

希望这会有所帮助!祝你好运!

,

步骤1: 在 pubspec.yaml 文件

中添加提供者模式的依赖项
dependencies:
  flutter:
    sdk: flutter
  provider: ^4.1.2

步骤2: 在单独的文件中创建提供程序:

class ViewTotalItemProvider with ChangeNotifier{
List<CartPlantLists> _cartPlantList1 = [];
get cartPlantList1 => _cartPlantList1 ;

  set cartPlantList1 (List<CartPlantLists> selected){
   _cartPlantList1 = selected;
     notifyListeners();
  }
}

步骤3: 使用MultiProvider将MaterialApp小部件包装在 main.dart 中。


void main() => runApp(
   MultiProvider (providers: [
      ChangeNotifierProvider<ViewTotalItemProvider>.value(value: 
          ViewTotalItemProvider()),child: MyApp()
                )
            );
class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
        home: HomePage(),);
  }
}

第4步: 在屏幕PlantFeatureScreen1中使用提供程序:

class PlantFeatureScreen1 extends StatefulWidget {
  @override
  _PlantFeatureScreen1State createState() => _PlantFeatureScreen1State();
}

class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {
  var viewTotalItemProvider;
  @override
  Widget build(BuildContext context) {
    viewTotalItemProvider = Provider.of<ViewTotalItemProvider>(context);
    return Scaffold(
      .......
    );
  }
  }

步骤5: 获取cartPlantList1。

     List<CartPlantLists> list = viewTotalItemProvider.cartPlantList1; 

第6步:设置cartPlantList1。

    List<CartPlantLists> list = [];
    ...
    viewTotalItemProvider.cartPlantList1 = list;

类似地,您可以将其用于其他两个类。