如何从父级窗口小部件或其他将来的构建器外部访问将来的构建器中的功能

时间:2020-05-13 15:04:16

标签: flutter dart

我有一个将来的构建器,它会填充一个列表视图,里面有一个函数total()来计算,选择每个项目的价格,将其总和并将其分配给小计变量。在底部,我显示的是总价格,如果我将小计变量设置为小计,则它将首次返回0,因为我的函数位于“将来的构建器”中,这意味着该函数将在赋值后执行。所以我使用了另一个“将来的构建器”显示总金额,但我无法访问总功能,因为它位于将来的构建器内部,并且无法在类的外部初始化,因为它具有一些外部无法识别的数据。 所以问题是我该如何访问下面的全部功能,想到了全局键,但我不知道如何使用它。

import 'package:flutter/material.dart';
import 'package:restaurant_ui_kit/models/user.dart';
import 'package:restaurant_ui_kit/screens/checkout.dart';
import 'package:restaurant_ui_kit/util/database_helper.dart';

class CartScreen extends StatefulWidget {
  @override
  _CartScreenState createState() => _CartScreenState();
}

class _CartScreenState extends State<CartScreen>
    with AutomaticKeepAliveClientMixin<CartScreen> {
  var db = new DatabaseHelper();
  int _subTotal = 0;
  List _users = [];

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.fromLTRB(10.0, 0, 10.0, 0),

        child: FutureBuilder<List>(
          future: db.getAllUsers(),
          initialData: List(),
          builder: (context, snapshot) {
            return snapshot.hasData
                ? ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, position) {
                      final item = snapshot.data[position];

                   total(){


                        for (int i = 0; i < snapshot.data.length; i++) {
                        if (i == 0){
                          _subTotal =0;
                        }
                        _subTotal = _subTotal +
                            int.parse(
                                User.fromMap(snapshot.data[position]).price);
                      }
                      return _subTotal;
                   }

                   total();

                    //  print('toatl is $_subTotal');

                      // get your item data here ...
                      return Dismissible(
                        key: UniqueKey(),
                        child: new Card(
                          color: Colors.white,
                          elevation: 2.0,
                          child: new ListTile(
                            leading: new CircleAvatar(
                              child: Text(
                                  "${User.fromMap(snapshot.data[position]).name.substring(0, 1)}"),
                            ),
                            title: new Text(
                                "User: ${User.fromMap(snapshot.data[position]).price}"),
                            subtitle: new Text(
                                "Id: ${User.fromMap(snapshot.data[position]).id}"),
                            onTap: () => debugPrint(
                                "${User.fromMap(snapshot.data[position]).id}"),
                          ),
                        ),
                        background: slideLeftBackground(),
                        confirmDismiss: (direction) async {
                          if (direction == DismissDirection.endToStart) {
                            final bool res = await showDialog(
                                context: context,
                                builder: (BuildContext context) {
                                  return AlertDialog(
                                    content: Text(
                                        "Are you sure you want to delete ${User.fromMap(snapshot.data[position]).name}?"),
                                    actions: <Widget>[
                                      FlatButton(
                                        child: Text(
                                          "Cancel",
                                          style: TextStyle(color: Colors.black),
                                        ),
                                        onPressed: () {
                                          Navigator.of(context).pop();
                                        },
                                      ),
                                      FlatButton(
                                        child: Text(
                                          "Delete",
                                          style: TextStyle(color: Colors.red),
                                        ),
                                        onPressed: () {
                                          // TODO: Delete the item from DB etc..
                                          setState(() {
                                            // total();
                                            // print(position);

                      print('toatl is $_subTotal');


                                            if (position == 0) {
                                              //print('index 0 dai');
                                              db.deleteUser(User.fromMap(
                                                      snapshot.data[position])
                                                  .id);
                                                  _subTotal = 0;
                     // print('toatl is 0 $_subTotal');


                                              //snapshot.data.removeAt(position);
                                            } else {
                                              snapshot.data
                                                  .removeAt(--position);
                                              db.deleteUser(User.fromMap(
                                                      snapshot.data[position])
                                                  .id);
                                                   total();
                     // print('toatl sewa $_subTotal');


                                            }

                                            //print("removed");
                                            // print('mSubTotal $mSubTotal');
                                          });
                                          Navigator.of(context).pop();
                                        },
                                      ),
                                    ],
                                  );
                                });
                            return res;
                          }
                        },
                      );
                    },
                  )
                : Center(
                    child: CircularProgressIndicator(),
                  );
          },
        ),

      ),
      floatingActionButton: FloatingActionButton(
        tooltip: "Checkout",
        onPressed: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (BuildContext context) {
                return Checkout();
              },
            ),
          );
        },
        child: Icon(
          Icons.arrow_forward,
        ),
        heroTag: Object(),
      ),

  bottomSheet: Card(
        elevation: 4.0,
        child: Container(

          child: ListView(
            physics: NeverScrollableScrollPhysics(),
            children: <Widget>[
SizedBox(height: 10.0),

              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.fromLTRB(10,5,5,5),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Total",
                          style: TextStyle(
                            fontSize: 13,
                            fontWeight: FontWeight.w400,
                          ),
                        ),

            FutureBuilder(
            **future: total(),**  the problem is here it cannot be accessed
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if(snapshot.hasData){
                return Text(
                  snapshot.data.toString(),
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 8,
                  ),
                  textAlign: TextAlign.center,
                );
              }
              return Container();
            }
          ),

                        Text(
                          "Delivery charges included",
                          style: TextStyle(
                            fontSize: 11,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                      ],
                    ),
                  ),

                  Container(
                    padding: EdgeInsets.fromLTRB(5,5,10,5),
                    width: 150.0,
                    height: 50.0,
                    child: FlatButton(
                      color: Theme.of(context).accentColor,
                      child: Text(
                        "Place Order".toUpperCase(),
                        style: TextStyle(
                          color: Colors.white,
                        ),
                      ),
                      onPressed: (){},
                    ),
                  ),

                ],
              ),



            ],
          ),

          height: 70,
        ),
      ),



    );
  }

  @override
  bool get wantKeepAlive => true;
}

2 个答案:

答案 0 :(得分:0)

首先,您可以取出total函数,并在data参数在futurebuilder中可用后再传递它(例如total(data){...})。
现在,如果您需要从db.getAllUsers()获得的数据,则还可以创建一个类似getAllUsers的函数,在该函数中,将获得的值分配给一个类变量,以供以后使用。最后,除非函数total是异步的,否则没有必要为其提供将来的构建器。一旦总值可用,您就可以调用setState逃脱。

答案 1 :(得分:0)

尝试一下

 @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.fromLTRB(10.0, 0, 10.0, 0),
        child: FutureBuilder<List>(
          future: db.getAllUsers(),
          initialData: List(),
          builder: (context, snapshot) {
            total() {
              num subTotal = 0;

              for (int i = 0; i < snapshot.data.length; i++) {
                subTotal += int.parse(User.fromMap(snapshot.data[i]).price);
              }
              setState(() {
                _subTotal=subTotal;
              }); 
            }

            if (snapshot.hasData) {
              ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, position) {
                  final item = snapshot.data[position];

                  total();

                  //  print('toatl is $_subTotal');

                  // get your item data here ...
                  return Dismissible(
                    key: UniqueKey(),
                    child: new Card(
                      color: Colors.white,
                      elevation: 2.0,
                      child: new ListTile(
                        leading: new CircleAvatar(
                          child: Text(
                              "${User.fromMap(snapshot.data[position]).name.substring(0, 1)}"),
                        ),
                        title: new Text(
                            "User: ${User.fromMap(snapshot.data[position]).price}"),
                        subtitle: new Text(
                            "Id: ${User.fromMap(snapshot.data[position]).id}"),
                        onTap: () => debugPrint(
                            "${User.fromMap(snapshot.data[position]).id}"),
                      ),
                    ),
                    background: slideLeftBackground(),
                    confirmDismiss: (direction) async {
                      if (direction == DismissDirection.endToStart) {
                        final bool res = await showDialog(
                            context: context,
                            builder: (BuildContext context) {
                              return AlertDialog(
                                content: Text(
                                    "Are you sure you want to delete ${User.fromMap(snapshot.data[position]).name}?"),
                                actions: <Widget>[
                                  FlatButton(
                                    child: Text(
                                      "Cancel",
                                      style: TextStyle(color: Colors.black),
                                    ),
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                    },
                                  ),
                                  FlatButton(
                                    child: Text(
                                      "Delete",
                                      style: TextStyle(color: Colors.red),
                                    ),
                                    onPressed: () {
                                      // TODO: Delete the item from DB etc..
                                      setState(() {
                                        // total();
                                        // print(position);

                                        print('toatl is $_subTotal');

                                        if (position == 0) {
                                          //print('index 0 dai');
                                          db.deleteUser(User.fromMap(
                                                  snapshot.data[position])
                                              .id);
                                          _subTotal = 0;
                                          // print('toatl is 0 $_subTotal');

                                          //snapshot.data.removeAt(position);
                                        } else {
                                          snapshot.data.removeAt(--position);
                                          db.deleteUser(User.fromMap(
                                                  snapshot.data[position])
                                              .id);
                                          total();
                                          // print('toatl sewa $_subTotal');

                                        }

                                        //print("removed");
                                        // print('mSubTotal $mSubTotal');
                                      });
                                      Navigator.of(context).pop();
                                    },
                                  ),
                                ],
                              );
                            });
                        return res;
                      }
                      return null;
                    },
                  );
                },
              );
            }
            return Center(child: CircularProgressIndicator());
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        tooltip: "Checkout",
        onPressed: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (BuildContext context) {
                return Checkout();
              },
            ),
          );
        },
        child: Icon(
          Icons.arrow_forward,
        ),
        heroTag: Object(),
      ),
      bottomSheet: Card(
        elevation: 4.0,
        child: Container(
          child: ListView(
            physics: NeverScrollableScrollPhysics(),
            children: <Widget>[
              SizedBox(height: 10.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.fromLTRB(10, 5, 5, 5),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          "Total",
                          style: TextStyle(
                            fontSize: 13,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
// changes

                        Text(
                          _subTotal.toString(),
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 8,
                          ),
                          textAlign: TextAlign.center,
                        ),

                        Text(
                          "Delivery charges included",
                          style: TextStyle(
                            fontSize: 11,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                      ],
                    ),
                  ),
                  Container(
                    padding: EdgeInsets.fromLTRB(5, 5, 10, 5),
                    width: 150.0,
                    height: 50.0,
                    child: FlatButton(
                      color: Theme.of(context).accentColor,
                      child: Text(
                        "Place Order".toUpperCase(),
                        style: TextStyle(
                          color: Colors.white,
                        ),
                      ),
                      onPressed: () {},
                    ),
                  ),
                ],
              ),
            ],
          ),
          height: 70,
        ),
      ),
    );
  }