日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flutter 实例 - 加载更多的ListView

發布時間:2024/9/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter 实例 - 加载更多的ListView 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Dart4Flutter - 01 – 變量、類型和函數

Dart4Flutter – 02 –控制流 和異常

Dart4Flutter – 03 – 類和泛型

Dart4Flutter – 04 – 異步和庫

Dart4Flutter - 拾遺01 - flutter-dart環境搭建

Dart4Flutter - 不可變性

Flutter入門 - 狀態管理

Flutter 入門實例1

Flutter 入門 - Container 屬性詳解

Flutter 入門-本地訪問-MethodChannel

Flutter 實例 - 加載更多的ListView

Flutter 實例 - 從本地到Flutter通信 - Event Channels

本教程完成一個有加載更多的ListView,最終效果如下圖所示:

開始

首先我們只在列表中展示10個整數。

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請求,假設我們通過傳遞from和to參數,然后返回他們之間的數。我們將添加延遲時間,這樣看起來更像是網絡加載。具體代碼如下所示:

/// from - 包括, to - 不包括 /// 通過這個模擬http請求 Future<List<int>> fakeRequest(int from, int to) async { // 如果對Future不熟悉,可以參考 https://juejin.im/post/5b2c67a351882574a756f2ebreturn Future.delayed(Duration(seconds: 2), () {return List.generate(to - from, (i) => i + from);}); } 復制代碼

當用戶將列表滾動到最底,我們將會調用上面的方法。為了監聽列表是否已經滾動到最底,最簡單的方式就是給列表添加一個ScrollController,當列表滾動的時候,就會發出一個請求。但是防止頻繁的發送http請求,我們需要添加一個變量isPerformingRequest,表示是否有請求正在進行。只有當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,他被Center、Opacity、Padding所包裹。我們將用Opacity組件控制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上:

@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,),); } 復制代碼

最終效果如下:

處理空數據情況

下面是附加內容,處理當請求返回的數據為空時的晴空。我們通過ScrollController給ListView一些動畫。

_getMoreData() async {if (!isPerformingRequest) {setState(() => isPerformingRequest = true);List<int> newEntries = await fakeRequest(items.length, items.length); //returns empty listif (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;});} } 復制代碼

下面是完整的代碼:

import 'dart:async';import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return new MaterialApp(theme: new ThemeData(primarySwatch: Colors.blue),home: new MyHomePage(),);} }class MyHomePage extends StatefulWidget {@override_MyHomePageState createState() => _MyHomePageState(); }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); //returns empty listif (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;});}}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(),),),);}@overrideWidget 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,),);} }/// from - inclusive, to - exclusive Future<List<int>> fakeRequest(int from, int to) async {return Future.delayed(Duration(seconds: 2), () {return List.generate(to - from, (i) => i + from);}); } 復制代碼

有任何問題,歡迎大家提問

參考

  • marcinszalek.pl/flutter/inf…

總結

以上是生活随笔為你收集整理的Flutter 实例 - 加载更多的ListView的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。