下拉刷新
很簡單,直接使用 RefreshIndicator 組件, onRefresh 為重新獲取數據的方法
Widget build(BuildContext context) {
return Scaffold(body: Container(padding: EdgeInsets.all(
2.0),child: RefreshIndicator(onRefresh: _refresh,backgroundColor: Colors.blue,child: ListView.builder(itemCount: _dataList.length,itemBuilder: (context, index) {
return ListItem(_dataList[index]);},),),),);}Future<
Null> _refresh()
async {_dataList.clear();
await _loadFirstListData();
return;}
復制代碼上拉加載更多
我們先看一下效果
class MyHomePage extends StatefulWidget {
@override_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<
int> items =
List.generate(
10, (i) => i);
@overridevoid initState() {
super.initState();}
@overridevoid dispose() {
super.dispose();}
@overrideWidget build(BuildContext context) {
return new Scaffold(appBar: AppBar(title: Text(
"Infinite ListView"),),body: ListView.builder(itemCount: items.length,itemBuilder: (context, index) {
return ListTile(title:
new Text(
"Number $index"));},),);}
}
復制代碼
- 現在我們要編寫一個加載更多數據的方法,用來模擬 http 請求
Future<
List<
int>> fakeRequest(
int from,
int to)
async {
return Future.delayed(
Duration(seconds:
2), () {
return List.generate(to - from, (i) => i + from);});
}
復制代碼
- 現在我們想要讓用戶將 ListView 滑動到最末端的觸發 fakeRequest 來加載更多數據,最簡單的實現方式就是使用 ScrollController 來完成,ScrollController 會監聽滾動事件,當 ListView 滾動到末端的時候他會發出一個請求。在這里還有一件需要注意的事就是為了避免對服務器不斷地請求,我們需要做一個標記 isPerformingRequest 只有當它為 false 的時候才允許對后臺進行請求。
class _MyHomePageState extends State<MyHomePage> {
List<
int> items =
List.generate(
10, (i) => i);ScrollController _scrollController =
new ScrollController();
bool isPerformingRequest =
false;
@overridevoid initState() {
super.initState();_scrollController.addListener(() {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {_getMoreData();}});}
@overridevoid dispose() {_scrollController.dispose();
super.dispose();}_getMoreData()
async {
if (!isPerformingRequest) {setState(() => isPerformingRequest =
true);
List<
int> newEntries =
await fakeRequest(items.length, items.length +
10);setState(() {items.addAll(newEntries);isPerformingRequest =
false;});}}
@overrideWidget build(BuildContext context) {
return new Scaffold(appBar: AppBar(title: Text(
"Infinite ListView"),),body: ListView.builder(itemCount: items.length,itemBuilder: (context, index) {
return ListTile(title:
new Text(
"Number $index"));},controller: _scrollController,),);}
}
復制代碼如果你現在運行程序你將會看到我們的列表已經可以實現動態加載了,但是這距離我們的目標還很遠,我們需要添加一些標志動作讓用戶這道請求已經開始。
- 接下來我們要用到 CircularProgressIndicator 去完成這個加載標志
Widget _buildProgressIndicator() {
return new Padding(padding:
const EdgeInsets.all(
8.0),child:
new Center(child:
new Opacity(opacity: isPerformingRequest ?
1.0 :
0.0,child:
new CircularProgressIndicator(),),),);
}
復制代碼- 現在我們將這個加載標志放到我們的 ListView 中去,注意這里要給 itemCount 加出一塊空間來放置我們的 _buildProgressIndicator
@override
Widget build(BuildContext context) {
return new Scaffold(appBar: AppBar(title: Text(
"Infinite ListView"),),body: ListView.builder(itemCount: items.length +
1,itemBuilder: (context, index) {
if (index == items.length) {
return _buildProgressIndicator();}
else {
return ListTile(title:
new Text(
"Number $index"));}},controller: _scrollController,),);
}
復制代碼- 到這里加載更多數據的功能基本完成了,為了更加美觀我們還要處理當沒有請求到更多數據的時候動作,在這里我們添加一個動畫沒有更多數據的時候 ListView 向下移動覆蓋正在加載更多數據的標志
_getMoreData()
async {
if (!isPerformingRequest) {setState(() => isPerformingRequest =
true);
List<
int> newEntries =
await fakeRequest(items.length, items.length);
if (newEntries.isEmpty) {
double edge =
50.0;
double offsetFromBottom = _scrollController.position.maxScrollExtent - _scrollController.position.pixels;
if (offsetFromBottom < edge) {_scrollController.animateTo(_scrollController.offset - (edge -offsetFromBottom),duration:
new Duration(milliseconds:
500),curve: Curves.easeOut);}}setState(() {items.addAll(newEntries);isPerformingRequest =
false;});}
}
復制代碼
總結
以上是生活随笔為你收集整理的Flutter下拉刷新,上拉加载更多数据的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。