颤动:如何在不按下按钮的情况下进行列表视图更新?
flutter: how to make a listview update without pressing a button?
所以我目前正在开发一个在第一个屏幕上有列表视图的应用程序(在 main.dart 上实现)。
列表视图从互联网(异步)获取数据。
问题是,当数据更改时,列表视图不会更新。
(我可以简单地通过设计一个 'reload' 按钮并在每次需要新数据时按下它来实现此功能。但这不是我现在想要的)。
换句话说,如何自动更新列表视图?
编辑 1:添加一些代码
代码可能很乱;见文末说明
class RssFeed extends StatelessWidget {
String title;
String pubDate;
RssFeed(this.title, this.pubDate);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Align(
alignment: Alignment.topRight,
child: Text(title),
),
Text(pubDate)
],
),
);
}
}
class FeedsList extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _FeedsListState();
}
}
class _FeedsListState extends State<FeedsList> {
List<Widget> list1 = new List<Widget>();
@override
void initState() {
super.initState();
ls();
}
Future ls() async {
list1.clear();
list.clear();
sites1.clear();
RSS_reader rss_reader = new RSS_reader();
for (var i in saver.list.items) {
sites1.add(
site(siteAdress: i.siteAdress, siteDescription: i.siteDescription));
}
var res = await rss_reader.Get_items(sites1);
for (var val in res) {
list.add(InkWell(
onTap: () => _launchURL(val.item.link),
child: Container(
height: 50,
color: Colors.amber[100],
child: Center(
child: new RssFeed(val.item.title, val.item.pubDate.toString()),
),
)));
}
print(list.length);
setState(() {
list1 = list;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: list1.length,
itemBuilder: (BuildContext context, int i) {
return list1[i];
}));
}
}
描述:
您可以猜到,这是一个 RSS reader。
所以,我有一个 class RSSFeed;这构成了 Listview 的一个图块。
然后在 FeedsList class(有状态小部件)中,我创建列表视图。
我有一个名为 RSS_reader 的 class 和一个方法 Get_items,它获取一堆网站作为输入并将这些网站的最新提要放入列表中(上面的 'res'代码)。
然后,我将项目放入“容器”列表中,然后构建列表视图。
然后,在主函数中,我创建了一个容器,如下所示:
容器(
身高:500,
宽度:580,
child:提要列表(),
)
出现了问题; FeedsList class 不会自动更新。尽管如果我放置一个按钮并通过该按钮导航到 FeedsList class,列表会刷新并确定。
感谢阅读和帮助。
您必须流式传输数据,ListView 会自动更新。
如果您只想从外部源获取数据一次,请使用 FutureBuilder,如果您想多次获取数据,请查看 StreamBuilder。两个小部件都将具有您正在寻找的行为,没有刷新按钮。
如何使用 FutureBuilder 的简单示例:
Future<List<String>> _fetchData() {
return // fetch data from source
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _fetchData,
builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasData && snapshot.data != null) {
// This widget will be built when data is fetched
const List<String> list = snapshot.data;
return ListView(
children: list.map(
(element) => ListTile(
title: Text(element),
),
).asList(),
);
} else {
// This widget will be built while you are waiting for your data to be fetched
return Container(
child: Center(
child: Text("Loading data..."),
),
);
}
},
);
}
在您说可以重新调用 ls() 函数的按钮中,您的列表应该会在点击按钮时更新
示例:
return Scaffold(
body: ListView.builder(
itemCount: list1.length,
itemBuilder: (BuildContext context, int i) {
return list1[i];
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
onPressed: () => ls(),
),
);
所以我目前正在开发一个在第一个屏幕上有列表视图的应用程序(在 main.dart 上实现)。 列表视图从互联网(异步)获取数据。 问题是,当数据更改时,列表视图不会更新。
(我可以简单地通过设计一个 'reload' 按钮并在每次需要新数据时按下它来实现此功能。但这不是我现在想要的)。
换句话说,如何自动更新列表视图?
编辑 1:添加一些代码 代码可能很乱;见文末说明
class RssFeed extends StatelessWidget {
String title;
String pubDate;
RssFeed(this.title, this.pubDate);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Align(
alignment: Alignment.topRight,
child: Text(title),
),
Text(pubDate)
],
),
);
}
}
class FeedsList extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _FeedsListState();
}
}
class _FeedsListState extends State<FeedsList> {
List<Widget> list1 = new List<Widget>();
@override
void initState() {
super.initState();
ls();
}
Future ls() async {
list1.clear();
list.clear();
sites1.clear();
RSS_reader rss_reader = new RSS_reader();
for (var i in saver.list.items) {
sites1.add(
site(siteAdress: i.siteAdress, siteDescription: i.siteDescription));
}
var res = await rss_reader.Get_items(sites1);
for (var val in res) {
list.add(InkWell(
onTap: () => _launchURL(val.item.link),
child: Container(
height: 50,
color: Colors.amber[100],
child: Center(
child: new RssFeed(val.item.title, val.item.pubDate.toString()),
),
)));
}
print(list.length);
setState(() {
list1 = list;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: list1.length,
itemBuilder: (BuildContext context, int i) {
return list1[i];
}));
}
}
描述: 您可以猜到,这是一个 RSS reader。 所以,我有一个 class RSSFeed;这构成了 Listview 的一个图块。 然后在 FeedsList class(有状态小部件)中,我创建列表视图。 我有一个名为 RSS_reader 的 class 和一个方法 Get_items,它获取一堆网站作为输入并将这些网站的最新提要放入列表中(上面的 'res'代码)。 然后,我将项目放入“容器”列表中,然后构建列表视图。
然后,在主函数中,我创建了一个容器,如下所示: 容器( 身高:500, 宽度:580, child:提要列表(), ) 出现了问题; FeedsList class 不会自动更新。尽管如果我放置一个按钮并通过该按钮导航到 FeedsList class,列表会刷新并确定。
感谢阅读和帮助。
您必须流式传输数据,ListView 会自动更新。
如果您只想从外部源获取数据一次,请使用 FutureBuilder,如果您想多次获取数据,请查看 StreamBuilder。两个小部件都将具有您正在寻找的行为,没有刷新按钮。
如何使用 FutureBuilder 的简单示例:
Future<List<String>> _fetchData() {
return // fetch data from source
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _fetchData,
builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasData && snapshot.data != null) {
// This widget will be built when data is fetched
const List<String> list = snapshot.data;
return ListView(
children: list.map(
(element) => ListTile(
title: Text(element),
),
).asList(),
);
} else {
// This widget will be built while you are waiting for your data to be fetched
return Container(
child: Center(
child: Text("Loading data..."),
),
);
}
},
);
}
在您说可以重新调用 ls() 函数的按钮中,您的列表应该会在点击按钮时更新
示例:
return Scaffold(
body: ListView.builder(
itemCount: list1.length,
itemBuilder: (BuildContext context, int i) {
return list1[i];
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
onPressed: () => ls(),
),
);