【发布时间】:2018-07-14 14:04:02
【问题描述】:
我正在尝试用新数据替换 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 987654325@ 变量。
如果数组的项目比前一个项目多,那么我会看到最后添加的新项目,但前一个(第一次渲染)项目保留在屏幕上。
我可以正确看到新数据,但在 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;
}
});
}
}
【问题讨论】: