ListView无法正确更新

时间:2018-07-14 14:04:02

标签: listview dart flutter

我正在尝试用新数据替换ListView,但是这样做并不符合预期。重点是

ListView.builder(
          itemBuilder: (context, i) {
            return Order(_orders[i]);
          }

_getOrders() async {
    String authToken = await Auth.getAuthToken();

    http.Response response = await http.get(
        API_URL + '?date=' + _formatDate(_activePeriod),
        headers: {'x-auth': authToken});

    var parsedJson = json.decode(response.body);


    setState(() {
      if (parsedJson.runtimeType.toString() != 'List<dynamic>') {
        _orders = [];
      } else {
        _orders = parsedJson;
      }
    });
  }

当应用启动时,第一个渲染是正确的,但是当我按Prev / Next按钮调用_changeMonth方法时,该方法又调用_getOrders,它在之后不会重新加载ListView我覆盖了_orders变量。 如果数组中的项目比以前的项目多,那么我会在末尾看到新添加的项目,但之前的(第一次渲染)项目仍保留在屏幕上。 我可以正确看到新数据,但是在API调用后不能覆盖_orders变量,因此不会在ListView中呈现新数据。除了使用setState()之外,我还需要做其他事情吗?

主文件的完整代码。 Order类是在其他文件中定义的,但我认为这里不是必需的。

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return HomeState();
  }
}

 class HomeState extends State {
      final DateTime _thisMonth = DateTime.now();
      DateTime _activePeriod = DateTime.now();

  final String app = 'Orders';

  List<dynamic> _orders = [];

  bool isLoggedIn = false;

  @override
  initState() {
    super.initState();
    Auth.init().then((loggedIn) {
      if (loggedIn) {
        setState(() {
          isLoggedIn = true;
        });
        _getOrders();
      }
    });
  }

  HomeState() {}

  @override
  build(BuildContext context) {
    return MaterialApp(
      title: app,
      home: Scaffold(
        appBar: new AppBar(
          title: Text(app),
        ),
        body: isLoggedIn
            ? ListView.builder(
          itemBuilder: (context, i) {
            return Order(_orders[i]);
          },
          itemCount: _orders.length,
        )
            : Auth.showLoginForm(),
        persistentFooterButtons: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[              
              FlatButton(
                child: Text('Prev'),
                onPressed: () {
                  _changeMonth(-1);
                },
              ),
              FlatButton(
                child: Text('Next'),
                onPressed: _activePeriod.month == _thisMonth.month
                    ? null
                    : () {
                  _changeMonth(1);
                },
              ),
            ],
          )
        ],
      ),
    );
  }

  _changeMonth(int increment) async {
    setState(() {
      _activePeriod =
          DateTime(_activePeriod.year, _activePeriod.month + increment, 1);
      _getOrders();
    });
  }

  _formatDate(DateTime date) {
    return '${date.year}/${date.month}/${date.day}';
  }

  _getOrders() async {
    String authToken = await Auth.getAuthToken();

    http.Response response = await http.get(
        API_URL + '?date=' + _formatDate(_activePeriod),
        headers: {'x-auth': authToken});

    var parsedJson = json.decode(response.body);
    //print(parsedJson);// new data appears fine
    setState(() {
      if (parsedJson.runtimeType.toString() != 'List<dynamic>') {
        _orders = [];
      } else {
        _orders = parsedJson;
      }
    });
  }
}

1 个答案:

答案 0 :(得分:1)

尝试为Dictionary<string, Func<double, Func<double, double>>> functions = new Dictionary<string, Func<double, Func<double, double>>> { {"+", a => b => a + b }, {"-", a => b => a - b }, {"*", a => b => a * b }, {"/", a => b => a / b }, {"^", a => b => Math.Pow(a, b) } }; functions.Add("Square", a => b => functions["^"](a)(2)); functions.Add("Sqrt", a => b => functions["^"](a)(0.5)); 添加密钥

Dictionary<string, Func<double, Func<double, double>>> functions = new Dictionary<string, Func<double, Func<double, double>>>()
        {
            {"+", a => b => a + b },
            {"-", a => b => a - b },
            {"*", a => b => a * b },
            {"/", a => b => a / b },
            {"^", a => b => Math.Pow(a, b) },
            {"Square", a => b => functions["^"](a)(2) },
            {"Sqrt", a => b => functions["^"](a)(0.5) }
        };

see article

  

您可以使用键来控制框架匹配的小部件   窗口小部件重建时与其他窗口小部件一起使用。默认情况下,框架   根据其匹配当前和先前版本中的小部件   runtimeType及其出现的顺序。使用键,   框架要求两个小部件具有相同的键,以及   相同的runtimeType。