I want to covert ListView
to CustomScrollView
so I need to convert my FutureBuilder
into SliverList
.
Here is my code:
class LatestNewsList extends StatefulWidget {
@override
_LatestNewsListState createState() => _LatestNewsListState();
}
class _LatestNewsListState extends State<LatestNewsList> {
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Data>>(
future: getQuake(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? NewsList(latestNews: snapshot.data,)
: Center(child: CircularProgressIndicator());
},
);
}
}
class NewsList extends StatelessWidget {
final List<Data> latestNews;
NewsList({this.latestNews});
@override
Widget build(BuildContext context) {
return new ListView.builder(
itemCount: latestNews.length,
itemBuilder: (context, index){
return new GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Browser(url: latestNews[index].post_link,)
)
);
},
child: new LatestNewsItem(
post_title: latestNews[index].post_title,
post_link: latestNews[index].post_link,
img_src: latestNews[index].img_src,
),
);
}
);
}
}
How to convert this same FutureBuilder logic into SliverList?
FutureBuilder is a Widget that will help you to execute some asynchronous function and based on that function's result your UI will update. FutureBuilder is Stateful by nature i.e it maintains its own state as we do in StatefulWidgets. Syntax: FutureBuilder( Key key, this. future, this.
In Flutter, with slivers, we can create different scrolling effects. Slivers give an amazing view of the lists when they scroll up or down. The slivers allow us to impact the Lists, Grids scrolling experience.
The children of a CustomScrollView
must be slivers, you can not use a FutureBuilder
.
Instead, rebuild the CustomScrollView
when the future completes:
// build fixed items outside of the FutureBuilder for efficiency
final someOtherSliver = SliverToBoxAdapter(...);
return FutureBuilder<List<Data>>(
future: getQuake(), // this is a code smell. Make sure that the future is NOT recreated when build is called. Create the future in initState instead.
builder: (context, snapshot){
Widget newsListSliver;
if(snapshot.hasData) {
newsListSliver = SliverList(delegate: SliverChildBuilderDelegate(...))
} else {
newsListSliver = SliverToBoxAdapter(child: CircularProgressIndicator(),);
}
return CustomScrollView(
slivers: <Widget>[
someOtherSliver,
newsListSliver
],
);
},
);
If you have multiple slivers which depend on Future
s or Stream
s, you can chain the builders:
return FutureBuilder<..>(
...
builder: (context, snapshot1) {
return FutureBuilder<..>(
...
builder: (context, snapshot2) {
return CustomScrollView(...);
}
)
}
)
Use SliverFillRemaining
Widget build(BuildContext context) {
return new Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.data == null)
return new Container(
child: Center(child: new CircularProgressIndicator()),
);
else
return Text(snapshot.data.name);
},
),
)
],
)
);
OR use SliverList
Widget build(BuildContext context) {
return new Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([Container(
child: FutureBuilder(
future : getData(),
builder: (C,snap){
//do whatever you want
}
)
)]),
)
]
)
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With