flutter Infinite Scrolling for ListView.builder
The easiest way is to use a ListView.builder
without specifying the itemCount
parameter.
Here is the simplest example:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Infinite List"),
),
body: ListView.builder(
itemBuilder: (context, index) {
return Text("$index");
},
),
);
}
}
Later, you can enhance this by fetching real data. You could show a 'CircularProgressIndicator' in the last item of the list while waiting for the new data.
body: ListView.builder(
itemBuilder: (context, index) {
if (index < data.length) {
// Show your info
return Text("$index");
} else {
getMoreData();
return Center(child: CircularProgressIndicator());
}
},
itemCount: data.length + 1,
),
You can see that we trick the list by adding an index, and calling for more data when displaying that final index.
getMoreData()
would include a call to setState()
to force a rebuild and to take into account the new data.
Admin
Updated on December 16, 2022Comments
-
Admin over 1 year
I've to use graphql query and I've got data page by page. so I need to Infinite Scrolling in my list view builder but I don't know how to add num in page. can anyone help me, please?
this is my query:
query homeview(\$moreId: ID!, \$page: Int! ){ homeview(HM_ID: \$moreId, page: \$page){ HM_ID HM_Type_ID HM_Type_Name } } """;
and this is my variable to pass int number in
page
:dynamic pageNum = 0;
here is the controller :
ScrollController _scrollController = new ScrollController( initialScrollOffset: 10,
and this is my list view builder:
class MoreEpd extends StatefulWidget { final String moreId; const MoreEpd({Key? key, required this.moreId}) : super(key: key); @override _MoreEpdState createState() => _MoreEpdState(); } class _MoreEpdState extends State<MoreEpd> { double pageWidth = 0; double pageHeigh = 0; dynamic pageNum = 0; final String leftArrow = 'assets/icons/left-arrow.svg'; String getSearchResult = """ query homeview(\$moreId: ID!, \$page: Int! ){ homeview(HM_ID: \$moreId, page: \$page){ HM_ID Priority Details{ Ep_ID Image title Pod_title } } } """; @override Widget build(BuildContext context) { pageWidth = MediaQuery.of(context).size.width; pageHeigh = MediaQuery.of(context).size.height; return Container( child: Query( options: QueryOptions( document: gql(getSearchResult), variables: {'moreId': widget.moreId, 'page': pageNum}, ), builder: ( QueryResult result, { Refetch? refetch, FetchMore? fetchMore, }) { return handleResult(result); }, ), ); } Widget handleResult(QueryResult result) { var data = result.data!['homeview']['Details'] ?? []; return Container( child: ListView.builder( padding: EdgeInsets.only(top: 15), shrinkWrap: true, itemCount: data.length , itemBuilder: (context, index) { return InkWell( onTap: () {}, child: Padding( padding: EdgeInsets.only( top: pageWidth * 0.0, right: pageWidth * 0.08, left: pageWidth * 0.08, bottom: pageWidth * 0.0), child: Container( child: Stack( children: [ Column( children: [ Padding( padding: EdgeInsets.only(bottom: pageWidth * 0.060), child: Row( children: [ Padding( padding: EdgeInsets.only(left: pageWidth * 0.01), child: Container( // alignment: Alignment.centerRight, width: pageWidth * 0.128, height: pageWidth * 0.128, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: CachedNetworkImageProvider( data[index]['Image'], )), borderRadius: BorderRadius.all( Radius.circular(15)), // color: Colors.redAccent, border: Border.all( color: MyColors.lightGrey, width: 1, )), ), ), Expanded( child: Row( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: pageWidth * 0.5, alignment: Alignment.centerRight, child: Text( data[index]['title'], textAlign: TextAlign.right, overflow: TextOverflow.ellipsis, maxLines: 1, // softWrap: true, style: TextStyle( // fontWeight: FontWeight.bold, fontSize: 14, ), ), ), ], ), ], ), ) ], ), ), ], ), ], ), ), ), ); })); }}
can anyone help me please how can I use infinite scrolling to load other pages in my query?
-
quim over 2 yearswhy do you need infinite scroll? listview.builder will be as big as it needs to fit all data
-
Admin over 2 yearsbecause I should pass int num to
page
query and get data from it.
-
-
Admin over 2 yearswhat is getMoreData()? class or method?
-
Admin over 2 yearsI don't know what I should put in getMoreData . i just want to
pageNum +=1;
this happen and load more data -
Infostans over 2 years@stysh it is function _getMoreData() async { final moreItems = await widget.onRequest(items.length); if (!mounted) return; if (moreItems.isEmpty) { setState(() => end = true); return; } setState(() => items = [...items, ...moreItems]); }
-
Infostans over 2 years@stysh also you can check this tutorial dartpad.dev/… . If it helps then please upvote it
-
Admin over 2 years@lnfostans it's cool but I can't match it with my project. I upload my class in question. Would you please see it and tell me how can I do it?