我目前正在尝试使用“拉动刷新”在Flutter中实现刷新功能。 “拉动刷新”将要做的是从后端检索任何新任务,并使用它来更新UI。虽然我可以使用onRefresh
字段来使用REST API(方法为fetchTasks
)来获取更新的任务,但是我不确定如何更新/重建UI来显示此信息。新任务。特别是,如何在不更改buildListViewWidget
方法中看到的FutureBuilder的使用的情况下实现这一目标。任何帮助将不胜感激!代码的关键部分如下所示
main.dart
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
new GlobalKey<RefreshIndicatorState>();
Future<Null> refreshList() {}
@override
Widget build(BuildContext context) {
// Widget that holds the title section
return MaterialApp(
title: 'learning',
home: Scaffold(
appBar: AppBar(
title: Text('Todo list'),
),
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: fetchTask,
child: ListView(
children: [
Image.asset(
'images/lake.jpg',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
buildListViewWidget(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Flexible(
child: Padding(
padding: const EdgeInsets.fromLTRB(
32.0, 0.0, 0.0, 16.0),
child: TextField(
controller: myController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Please enter a todo task',
),
))),
Padding(
padding: const EdgeInsets.fromLTRB(
0.0, 0.0, 32.0, 16.0),
child: RaisedButton(
child: const Text('Submit'),
color: Colors.red,
highlightColor: Colors.blue,
elevation: 4.0,
onPressed: () {
String temp = myController.text;
myController.clear();
Map map = {'task': temp};
apiRequest(post_url, map);
},
))
]),
],
)
)
)
);
}
FutureBuilder<List<Task>> buildListViewWidget() {
return new FutureBuilder<List<Task>>(
future: fetchTask(),
builder: (context, snapshot) {
if (snapshot.hasData) {
print("Data is present");
return new ListGenerator(todoList: snapshot.data);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return Center(child: CircularProgressIndicator());
});
}
list_generator.dart
import 'package:flutter/material.dart';
import 'task.dart';
class ListGenerator extends StatefulWidget {
final List<Task> todoList;
ListGenerator({Key key, this.todoList}) : super(key: key);
@override
_ListGeneratorState createState() => _ListGeneratorState();
}
class _ListGeneratorState extends State<ListGenerator> {
final _biggerFont = const TextStyle(fontSize: 18.0);
Widget build(BuildContext context) {
Widget _buildTodoList() {
return ListView.separated(
physics: const ScrollPhysics(),
itemCount: widget.todoList == null ? 0 : widget.todoList.length,
separatorBuilder: (BuildContext, int index) => Divider(),
shrinkWrap: true,
padding: const EdgeInsets.all(32.0),
itemBuilder: (context, i) {
return ListTile(
title: Text(
widget.todoList[i].getTask(),
style: _biggerFont
),
trailing: new Icon(
Icons.delete,
color: Colors.grey
),
);
}
);
}
return _buildTodoList();
}
}
task_methods.dart
import 'task.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'list_generator.dart';
Future<List<Task>> fetchTask() async {
final response =
await http.get(BACKEND_URL);
if (response.statusCode == 200) {
print(response.body);
// If the call to the server was successful, parse the JSON
return compute(parseData, response.body);
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
List<Task> parseData(String response) {
final parsed = json.decode(response);
return (parsed["data"] as List).map<Task>((json) =>
new Task.fromJson(json)).toList();
}