我的仪表板代码如下所示,
在这里,我在getReport方法中执行get req,我在代码中添加了RefreshIndicator
,当在容器中将其下拉时应该刷新,在这里调用了getData(),但是我没有得到刷新的内容,我在下面添加了我的代码,让我知道是否在任何地方出错。
在我的dashboard.dart下方
class Window extends StatefulWidget {
@override
_WindowState createState() => _WindowState();
}
class _WindowState extends State<Window> {
Future reportList;
@override
void initState() {
super.initState();
reportList = getReport();
}
Future<void> getReport() async {
http.Response response =
await http.get(reportsListURL, headers: {"token": "$token"});
switch (response.statusCode) {
case 200:
String reportList = response.body;
var collection = json.decode(reportList);
return collection;
case 403:
break;
case 401:
return null;
default:
return 1;
}
}
getRefreshScaffold() {
return Center(
child: RaisedButton(
onPressed: () {
setState(() {
reportList = getReport();
});
},
child: Text('Refresh, Network issues.'),
),
);
}
getDashBody(var data) {
double maxHeight = MediaQuery.of(context).size.height;
return Column(
children: <Widget>[
Container(
height: maxHeight - 800,
),
Container(
margin: new EdgeInsets.all(0.0),
height: maxHeight - 188,
child: new Center(
child: new RefreshIndicator( //here I am adding the RefreshIndicator
onRefresh:getReport, //and calling the getReport() which hits the get api
child: createList(context, data),
),),
),
],
);
}
Widget createList(BuildContext context, var data) {
Widget _listView = ListView.builder(
itemCount: data.length,
itemBuilder: (context, count) {
return createData(context, count, data);
},
);
return _listView;
}
createData(BuildContext context, int count, var data) {
var metrics = data["statistic_cards"].map<Widget>((cardInfo) {
var cardColor = getColorFromHexString(cardInfo["color"]);
if (cardInfo["progress_bar"] != null && cardInfo["progress_bar"]) {
return buildRadialProgressBar(
context: context,
progressPercent: cardInfo["percentage"],
color: cardColor,
count: cardInfo["value"],
title: cardInfo["title"],
);
} else {
return buildSubscriberTile(context, cardInfo, cardColor);
}
}).toList();
var rowMetrics = new List<Widget>();
for (int i = 0; i < metrics.length; i += 2) {
if (i + 2 < metrics.length)
rowMetrics.add(Row(children: metrics.sublist(i, i + 2)));
else
rowMetrics.add(Row(children: [metrics[metrics.length - 1], Spacer()]));
}
return SingleChildScrollView(
child: LimitedBox(
// maxHeight: MediaQuery.of(context).size.height / 1.30,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: rowMetrics,
),
),
);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: reportList,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.done:
var data = snapshot.data;
if (snapshot.hasData && !snapshot.hasError) {
return getDashBody(data);
} else if (data == null) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text("Timeout! Log back in to continue"),
Padding(
padding: EdgeInsets.all(25.0),
),
RaisedButton(
onPressed: () {
setState(() {
token = null;
});
Navigator.of(context).pushReplacement(
CupertinoPageRoute(
builder: (BuildContext context) => LoginPage()),
);
},
child: Text('Login Again!'),
),
],
),
);
} else {
getRefreshScaffold();
}
}
},
);
}
}
答案 0 :(得分:8)
以下是StatefulWidget的State类,其中:
ListView
包装在RefreshIndicator
中
words
状态变量是其数据源onRefresh
调用_pullRefresh
函数来更新ListView
_pullRefresh
是一个异步函数,什么也不返回(Future<void>
)_pullRefresh
的长期数据请求完成时,words
成员/状态变量将在setState()
调用中进行更新以重建ListView
以显示新数据import 'package:english_words/english_words.dart';
class _PullToRefreshPageState extends State<PullToRefreshPage> {
List<WordPair> words = generateWordPairs().take(5).toList();
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: _pullRefresh,
child: ListView.builder(
itemCount: words.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(words[index].asPascalCase),
);
},),
);
}
Future<void> _pullRefresh() async {
List<WordPair> freshWords = await WordDataSource().getFutureWords(delay: 2);
setState(() {
words = freshWords;
});
// why use freshWords var? https://stackoverflow.com/a/52992836/2301224
}
}
class WordDataSource {
Future<List<WordPair>> getFutureWords({int size = 5, int delay = 5}) async {
await Future.delayed(Duration(seconds: delay));
return generateWordPairs().take(5).toList();
}
}
onRefresh
功能非常快速地完成,您可能想在其后添加一个await Future.delayed(Duration(seconds: 2));
,这样UX才更令人愉悦。 这是另一个使用FutureBuilder的示例,当从数据库或HTTP源获取数据时很常见
class _PullToRefreshFuturePageState extends State<PullToRefreshPage> {
Future<List<WordPair>> futureWords;
@override
void initState() {
super.initState();
futureWords = WordDataSource().getFutureWords(delay: 2);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<WordPair>>(
//initialData: [],
future: futureWords,
builder: (context, snapshot) {
return RefreshIndicator(
child: _listView(snapshot),
onRefresh: _pullRefresh,
);
},
);
}
Widget _listView(AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].asPascalCase),
);
},);
}
else {
return Center(
child: Text('Loading data...'),
);
}
}
Future<void> _pullRefresh() async {
List<WordPair> freshFutureWords = await WordDataSource().getFutureWords(delay: 2);
setState(() {
futureWords = Future.value(freshFutureWords);
});
}
}
getFutureWords()
函数与上面的基本示例中的函数相同,但是数据被包装在Future.value()
中,因为FutureBuilder期望使用Future
setState()
(在FutureBuilder示例中,futureWords
和{{1} }(在基本示例中),之后其长期运行的异步数据提取功能已完成。
words
,则会出现异常async
外部的成员变量并具有空的setState
闭包,可能会在将来导致手掌/代码分析警告答案 1 :(得分:0)
尝试一下:
onRefresh: () {
setState(() {});
}}
代替onRefresh:getReport
reportList
字段是Future
,它一次返回其值。因此,当您再次调用getReport
时,它什么都没有改变。实际上,更正确的是使用Stream
和StreamBuilder
而不是Future
和FutureBuilder
。但是对于此代码,这可能是最短的解决方案
答案 2 :(得分:0)
不确定期货,但是对于刷新指标,您必须返回空值,以便 使用类似
RefreshIndicator(
onRefresh: () async {
await getData().then((lA) {
if (lA is Future) {
setState(() {
reportList = lA;
});
return;
} else {
setState(() {
//error
});
return;
}
});
return;
},
尝试一下,让我知道!
编辑:
好吧,然后在您的刷新方法中尝试一下
setState(() {
reportList = getReport();
});
return reportList;
答案 3 :(得分:0)
简单的方法:你可以使用下拉刷新包 - https://pub.dev/packages/pull_to_refresh