Author : Li Juncai (jcLee95) : https://blog.csdn.net/qq_28550263
Email: [email protected]
Article address : https://blog.csdn.net/qq_28550263/article/details/133342307
There is another version of this article, based on GetX simple state management state. The address is: https://jclee95.blog.csdn.net/article/details/133365040
Table of contents
1. Infinite scrolling list
In Flutter, implementing an endless scrolling list usually involves using a ListView, ListView.builder, or ListView.separated component, combined with a data source and a scroll controller. This allows you to load and display large amounts of data, dynamically loading more data only when needed, for an endless scrolling effect.
2. Basic implementation example of simulating a scrolling list (ListView.builder)
2.1 Introduction to implementation ideas and steps
The following are the general steps to implement Flutter's endless scrolling list:
Prepare data source
First you need to have a data source. For example, a list or a database query result, or data requested from the network for list rendering. Typically, this data should be loaded on demand rather than loading all at once.
Create a scroll controller
Create a scroll controller through ScrollController to listen for scroll events of the list. This will help you determine when to load more data.
Build a list view
Build a list view using ListView.builder , which creates a list that renders only visible items. Define how each list item is rendered by specifying the itemBuilder parameter.
Set up scroll monitoring
Add a scroll controller to the list view and use addListener to listen for scroll events. As the user scrolls through the list, an action to load more data can be triggered at the appropriate time.
load more data
When you need to load more data, you can call the data source's methods or request data. This could be fetching data from the network, querying data from a local database, or other means. Once the data is ready, add it to the data source and then tell the list view to rebuild.
Update list view
When new data is available, call the setState method to notify Flutter to rebuild the list view. This will cause the list view to load and display the new data.
2.2 A simple example
According to the steps in Section 2.1, an example of implementing a simulated wireless scroll is as follows:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({
Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
home: InfiniteScrollList(),
);
}
}
/// 一个带有无尽滚动列表的 StatefulWidget。
class InfiniteScrollList extends StatefulWidget {
const InfiniteScrollList({
Key? key}) : super(key: key);
State<InfiniteScrollList> createState() => _InfiniteScrollListState();
}
/// [InfiniteScrollList] 的状态类,包含滚动逻辑和数据管理。
class _InfiniteScrollListState extends State<InfiniteScrollList> {
List<int> items = List.generate(20, (index) => index); // 初始数据
final ScrollController _scrollController = ScrollController();
bool isLoading = false;
void initState() {
super.initState();
_scrollController.addListener(_loadMore);
}
/// 处理滚动事件以加载更多数据。
void _loadMore() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent &&
!isLoading) {
// 模拟加载更多数据
setState(() {
isLoading = true;
});
// 模拟加载数据的延迟
Future.delayed(const Duration(seconds: 2), () {
setState(() {
// 添加新数据到现有列表中
items.addAll(List.generate(10, (index) => index + items.length));
isLoading = false;
});
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('无尽滚动列表'),
),
body: ListView.builder(
controller: _scrollController,
itemCount: items.length + (isLoading ? 1 : 0),
itemBuilder: (context, index) {
if (index < items.length) {
return ListTile(
title: Text('Item ${
items[index]}'),
);
} else {
// 显示加载指示器
return const Padding(
padding: EdgeInsets.all(16.0),
child: Center(child: CircularProgressIndicator()),
);
}
},
),
);
}
void dispose() {
// 释放滚动控制器
_scrollController.dispose();
super.dispose();
}
}
The code above InfiniteScrollList
is one StatefulWidget
, which contains an infinitely scrollable list view that can automatically load more data. First, in the initial state, the list contains 20 integer items. When the user scrolls to the bottom of the list, it simulates loading more data. When more data is loaded, a loading indicator is displayed. The effect is as shown in the figure:
Now we summarize the following implementation ideas. _InfiniteScrollListState
First, in the class, we use List.generate
to create a list containing the initial data that will be used for the initial display. Next create an ScrollController
object _scrollController
that will listen to the list's scroll events.
- In
initState
the method, add a scroll listener_scrollController
to trigger loading more data when the user scrolls to the bottom. _loadMore
The method handles the scroll event, checks whether the scroll has reached the bottom of the list, and if so and is not loading, simulates the process of loading more data.- In
build
the method, use toListView.builder
build the list view. If the user scrolls to the bottom of the list, a loading indicator appears. - In
dispose
the method, release_scrollController
to prevent memory leaks.
Specific implementation steps include:
Here are the steps to implement an infinite scrolling list:
-
Create a Flutter application.
-
Create a
StatefulWidget
container for an infinite scrolling list. -
In the state class, initialize the data source, including the initial data list.
-
Create a scroll controller (
ScrollController
) andinitState
add a scroll listener to it in the method. -
In the scroll listener, check if you have scrolled to the bottom of the list and load more data if necessary.
-
Use to
ListView.builder
build a list view and dynamically generate list items based on the data source. -
Displays a loading indicator at the bottom of the list to indicate that more data is being loaded.
-
dispose
Release the scroll controller in the method .
With these steps, you can implement an infinite scrolling list that users can scroll through and load more data, creating an infinite scrolling experience. This is useful for applications that need to display large amounts of data, such as social media news feeds or product lists.
3. Transformation 1: Basic implementation example of Taobao-like wireless scrolling grid (GridView.builder)
The basic principle is similar to the wireless scrolling list. The steps required to transform the GridView to simulate infinite scrolling include:
- Create a data source: First, you need to prepare a data source, which can be a list containing product information.
- Create a scroll view: Replace ListView.builder with GridView.builder to create a grid view. Set the gridDelegate to specify the number of columns and layout.
- Scroll Listening: Use a ScrollController to listen for scroll events, similar to the previous example, to determine when to trigger an action to load more data.
- Dynamic loading trigger: In the scroll listener, check whether the scroll position is close to the bottom, and if so, trigger the operation of loading more data.
- Update the data source: When the trigger loads more data, update the data source, usually by getting new data from the network or other data sources, and adding it to the data source.
- Rebuild the UI: Use setState() to notify Flutter to rebuild the UI to display the newly loaded data.
The specific implementation code is as follows:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({
Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
home: InfiniteScrollGrid(),
);
}
}
class InfiniteScrollGrid extends StatefulWidget {
const InfiniteScrollGrid({
Key? key}) : super(key: key);
State<InfiniteScrollGrid> createState() => _InfiniteScrollGridState();
}
class _InfiniteScrollGridState extends State<InfiniteScrollGrid> {
List<String> items = List.generate(20, (index) => 'Item $index'); // 初始数据
final ScrollController _scrollController = ScrollController();
bool isLoading = false;
void initState() {
super.initState();
_scrollController.addListener(_loadMore);
}
void _loadMore() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent &&
!isLoading) {
setState(() {
isLoading = true;
});
Future.delayed(const Duration(seconds: 1), () {
setState(() {
items.addAll(
List.generate(10, (index) => 'Item ${
index + items.length}'));
isLoading = false;
});
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('无尽滚动网格'),
),
body: GridView.builder(
controller: _scrollController,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 列数
childAspectRatio: 0.7, // 网格项的宽高比
),
itemCount: items.length + (isLoading ? 1 : 0),
itemBuilder: (context, index) {
if (index < items.length) {
return Card(
elevation: 3,
margin: const EdgeInsets.all(8),
child: Text(items[index]),
);
} else {
return const Padding(
padding: EdgeInsets.all(16.0),
child: Center(child: CircularProgressIndicator()),
);
}
},
),
);
}
void dispose() {
_scrollController.dispose();
super.dispose();
}
}
The implementation effect of this code is: