首页 > 解决方案 > 如何从外部父小部件或另一个未来构建器访问未来构建器内部的功能

问题描述

我有一个填充列表视图的未来构建器,里面有一个函数 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;
}

标签: flutterdart

解决方案


尝试这个

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

推荐阅读