In actual apps, pull-down refresh and slide up loading are more common forms of interaction. In the Flutter, there is a Flutter_ The easyrefresh open source plug-in is used to implement pull-down refresh and slide up load. This article introduces stateful components and fluent_ The basic application of easyrefresh completes asynchronous data loading by simulation.
Stateful component
When the data needs to be dynamically updated on the page of fluent, the UI components need to be updated according to the data changes, which means that the components have a "state". This is similar to the class components and function components of React (only the subsequent React uses the hook function to implement the function components, and the function components can also have states). In fluent, components are also divided into stateless components and stateful components. Generally, stateless components are used as much as possible. However, if the component itself needs to maintain its own state, it needs to use stateful components. Stateful components are defined as follows:
//Stateful component declaration class DynamicPage extends StatefulWidget { DynamicPage({Key key}) : super(key: key); //Create component status @override _DynamicPageState createState() => _DynamicPageState(); } //Component status class _DynamicPageState extends State<DynamicPage> { @override Widget build(BuildContext context) { //UI build } }
The actual business logic of stateful components is implemented by corresponding states, including data definition and UI construction. Its core is that there is a setState method to notify the interface to refresh (which is similar to React). Once the setState method is actively called, the interface will be refreshed. Of course, there are other state related methods, such as the state initialization method initialState.
Asynchronous async/await
Asynchronous requests are inevitable in network requests, and async and await are needed at this time. The return result of the function marked async is an object wrapped in Future, from which the caller can obtain the actual returned data using await. The async/await pairing completes an asynchronous call process. When the result is not returned, the main thread will perform other tasks. Here, we change the list data acquisition method to async to simulate the network request, as shown below:
static Future<List<Map<String, Object>>> list(int page, int size) async { return List<Map<String, Object>>.generate(size, (index) { return { 'title': 'title ${index + (page - 1) * size + 1}: This is a list title, up to two lines, and multiple parts will be intercepted', 'imageUrl': 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3331308357,177638268&fm=26&gp=0.jpg', 'viewCount': 180, }; }); }
When calling, use await to obtain the actual result data, as shown below:
// _ currentPage is the current page number, PAGE_SIZE is the paging size List<Map<String, Object>> _newItems = await DynamicMockData.list(_currentPage, PAGE_SIZE);
Introduction of fluent_ easyrefresh
When flutter needs to introduce a third-party plug-in, it needs to add dependencies under the dependencies node in the pubspec.yaml file. When writing this article, flutter_ The latest version of easyrefresh is 2.2.1, so the specified version is as follows:
dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 flutter_easyrefresh: ^2.2.1
After adding dependencies, you need to execute the shuttle pub get command in the project directory to update dependencies (VSCode will be automatically pulled when detecting changes in pubspec.yaml).
Using fluent_ easyrefresh
On the list in the previous article( Introduction and practice of Flutter (V): a list with pictures and texts )The transformation is divided into the following three steps:
- Modify the page as a stateful component to support data management and update the interface according to the data
- Use the EasyRefresh package list component and specify onRefresh and onLoad callback methods to respond to more actions of drop-down refresh and slide up load.
- Get the data according to the current page and update it to the list data, and then call setState to update the status data refresh interface.
The whole new dynamic_ The code of page is as follows:
import 'package:flutter/material.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'dynamic_item.dart'; import 'dynamic_mock_data.dart'; class DynamicPage extends StatefulWidget { DynamicPage({Key key}) : super(key: key); @override _DynamicPageState createState() => _DynamicPageState(); } class _DynamicPageState extends State<DynamicPage> { List<Map<String, Object>> _listItems = []; int _currentPage = 1; static const int PAGE_SIZE = 20; void _refresh() async { _currentPage = 1; _requestNewItems(); } void _load() async { _currentPage += 1; _requestNewItems(); } void _requestNewItems() async { List<Map<String, Object>> _newItems = await DynamicMockData.list(_currentPage, PAGE_SIZE); this.setState(() { if (_currentPage > 1) { _listItems += _newItems; } else { _listItems = _newItems; } }); } @override Widget build(BuildContext context) { return Scaffold( body: EasyRefresh( onRefresh: () async { _refresh(); }, onLoad: () async { _load(); }, child: ListView.builder( itemCount: _listItems.length, itemBuilder: (context, index) { return DynamicItem( _listItems[index]['title'], _listItems[index]['imageUrl'], _listItems[index]['viewCount'], ); }), ), ); } }
Operation results
The operation results are shown in the figure below. Because the pull-up load is too fast, it can not be seen directly in the screenshot. It should be noted that EasyRefresh will not be loaded automatically when it is loaded for the first time. At this time, EasyRefresh controller needs to be used for control. Interested students can refer to it flutter_easyfresh Document implementation.
epilogue
flutter_easyrefresh can achieve rich loading effects, including custom loading components, and even the use of interesting animations. It can basically meet the needs of all kinds of pull-down refresh or slide up loading. It is suggested that you can refer to the documentation to try other effects. If you are interested, you can also read the source code to see the specific implementation.