Flutter is the mobile App SDK by Google, which helps create modern mobile apps for iOS and Android using a single code base. It’s the new entrant in cross-platform mobile application development, and unlike other frameworks like React Native, it doesn’t use JavaScript but Dart as the Programming Language.
If you don’t know how to install Flutter, check out my how to install Flutter article. In real-world apps, dynamic content is always there, and it is fetched from a backend. So, we need to display those contents not to annoy the user while scrolling down the page.
What is Dynamic Content?
If you are building real-time applications, then the screen contents will change based on user actions and with a change in network data.
Most of the time, dynamic behavior is achieved by changing the contents displayed in the body. Flutter provides ListView.Builder() constructor, which can be used to generate dynamic content from external sources.
Unless the app is fundamental and created for learning purposes, it will always use dynamic data, i.e., the contents of a screen will change based on user actions and the change in network data.
Most of the time, dynamic behavior is achieved by changing the contents displayed in the body.
What we will build using Flutter ListView
In this tutorial, we will create a button widget, and when the button is pressed, it will add an item to the List and display that List on the mobile screen. So, when the button is pressed, the Widget state will change, and the UI will be re-rendered, and we will see the products list inside the mobile screen.
If the item’s length will be increased and reach the limit where we need to scroll down the page, then we need to display the scrollbar to scroll down the page quickly.
If we do not use ListView, it will throw a warning in a yellow line to indicate that we need to use some widget to show the proper user content, and that is why we will use the ListView widget Flutter.
Flutter ListView
Flutter provides ListView.builder
which can be used to generate dynamic content from external sources. There are four types of ListViews.
- ListView
- ListView.builder
- ListView.separated
- ListView.custom
ListView
ListView is the default constructor of a ListView class. A ListView takes the list of children and makes it scrollable.
Syntax
ListView( children: <Widget>[ ItemOne(), ItemTwo(), ItemThree(), ], ),
ListView.builder()
The builder() constructor constructs the repeating list of items. The constructor takes two main parameters:
1) An itemCount for the number of items in the List and the itemBuilder for constructed each list item.
Syntax
ListView.builder( itemCount: itemCount, itemBuilder: (context, position) { return listItem(); }, ),
The list items are constructed lazily, meaning only a specific number of list items are constructed, and when the user scrolls ahead, the earlier ones are destroyed.
ListView.separated()
In the separated() constructor, we generate the list, and we can specify the separator between each item.
In essence, we construct two interweaved lists: one as the main List, one as the separator list.
Note that the earlier constructor’s infinite count cannot be used here, which enforces an itemCount.
ListView.separated( itemBuilder: (context, position) { return ListItem(); }, separatorBuilder: (context, position) { return SeparatorItem(); }, itemCount: itemCount, ),
This type of List lets you dynamically define separators, have different separators for different items, add or remove separators when needed, etc.
That implementation can also be used for inserting other types of elements (for example, advertisements) quickly and without any modification to the main List in the middle of the list items.
ListView example
The standard ListView constructor works well for small lists. However, if we want to work with many items lists, it’s best to use the ListView.builder constructor.
The main difference between ListView and ListView.builder is that the default ListView constructor requires us to create all items at once, whereas the ListView.builder constructor will create items as they are scrolled onto the screen like on-demand.
We will use a ListView.builder constructor for displaying the items. But, first, let us create a new app in the Visual Studio Code.
Step 1: Create a new flutter project
Go to the VSCode and hit the shortcut keys: cmd + shift + p and type the Flutter, and it will show to create a new project option, and it creates a new flutter project in your specified folder.
Also, create one folder called assets in the project’s root; we will copy one image to that folder to display inside the Flutter app.
Now, we are going to show an image from the local folder. So, we need to add an image inside the pubspec.yaml file.
Add the following line of code inside the pubspec.yaml file.
assets: - assets/macbook.jpg
There is already a commented line by default by Flutter; you need to uncomment it and replace the first line with the assets/your image file with an extension.
If you still do not know how to display the image inside the Flutter app, then check out How To Display Image in Flutter.
Step 2: Write the Stateful Widget
Now, if you do not know how to write the Stateful Widget in Flutter, then check out this article.
Write the following code inside the main.dart file.
// main.dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _MyAppState(); } } class _MyAppState extends State<MyApp> { List<String> _products = ['Laptop']; @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.deepPurple), home: Scaffold( appBar: AppBar(title: Text('Long List App')), body: Column(children: [ Container( margin: EdgeInsets.all(10.0), child: RaisedButton( color: Theme.of(context).primaryColor, splashColor: Colors.blueGrey, textColor: Colors.white, onPressed: () { setState(() { _products.add('Macbook'); }); }, child: Text('Add Laptops'))), Column( children: _products .map((element) => Card( child: Column( children: <Widget>[ Image.asset('assets/macbook.jpg'), Text(element, style: TextStyle(color: Colors.deepPurple)) ], ), )) .toList()), ]), ), ); } }
First, we have created a stateful widget and then set up the theme for the flutter application. Then we have taken one Raised Button, and when the user presses the button, we will add the laptop to the array and display that with the help of Card Widget.
We are displaying the two items.
- Image
- Text
Now, save a file and go to the terminal and type the following command.
flutter run -d all
Make sure; you have opened the iOS Simulator and Android Emulator. After the compilation process, you will see something like this.
Now, click on the Add Laptops button, and you will see the second item added into an array.
Now, try to add two or more items; you will see the yellow warning below.
To resolve this problem, we need a ListView.builder() Widget and let us that Widget.
Step 3: Add ListView.builder() widget
Let us understand the ListView.builder() widget.
ListView.builder constructor
It creates the scrollable, linear array of widgets that are created on-demand.
ListView.builder() constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are visible.
Providing the non-null itemCount improves the ability of the ListView to estimate the maximum scroll extent.
The itemBuilder callback will be called only with indices greater than or equal to zero and less than itemCount.
The next step is, we will split our codebase into two files.
- products.dart
- main.dart
The products.dart file is only responsible for displaying the items in the card widget with the ListView.builder constructor widget.
Create one file called products.dart inside the lib folder and add the following code.
// products.dart import 'package:flutter/material.dart'; class Products extends StatelessWidget { final List<String> products; Products(this.products); Widget _buildProductItem(BuildContext context, int index) { return Card( child: Column( children: <Widget>[ Image.asset('assets/macbook.jpg'), Text(products[index], style: TextStyle(color: Colors.deepPurple)) ], ), ); } @override Widget build(BuildContext context) { return ListView.builder( itemBuilder: _buildProductItem, itemCount: products.length, ); } }
So, this is the Products class, which has one method called _buildProductItem. This function returns the ListView.builder widget.
ListView.builder widget takes two arguments. One is a function that returns the Widget, and the second is itemCount, which is the length of an array of products.
Now, import the products.dart file inside the main.dart file.
// main.dart import 'package:flutter/material.dart'; import './products.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _MyAppState(); } } class _MyAppState extends State<MyApp> { List<String> _products = []; @override void initState() { super.initState(); _products.add('Laptop'); } @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(primarySwatch: Colors.deepPurple), home: Scaffold( appBar: AppBar(title: Text('Long List App')), body: Column(children: [ Container( margin: EdgeInsets.all(10.0), child: RaisedButton( color: Theme.of(context).primaryColor, splashColor: Colors.blueGrey, textColor: Colors.white, onPressed: () { setState(() { _products.add('Laptop'); }); }, child: Text('MacBook'))), Expanded(child: Products(_products)) ]))); } }
Here, we have used the Expanded Widget. It allows us to expands a child of a Row, Column, or Flex. Using an Expanded widget makes the child of a Row, Column, or Flex expand to fill the available space in the primary axis (e.g., horizontally for a Row or vertically for a Column). If multiple children are expanded, available space is divided among them according to the flex factor.
Here, we have passed the imported Products constructor with the argument of the _products array.
Save the file and restart the compilation using the shortcut key R and now, add more than 3 products and see that we are now getting the perfect scrollable view, and it will display the product on demand.
This is the most efficient way to display a long list with the ListView by not using ListView but using ListView.builder() constructor.
Finally, Flutter ListView Example is over.
Nice article 🙂
I chose to follow your “tutorial” because it’s easier to follow that most of what I’ve found.
I will take a look to your other posts soon.
I wish you the best !
For other readers, I had a bug that I fixed :
itemBuilder: (context, index) { _buildItem(index); }
It will show a blank page. You have to use it like that :
itemBuilder: (context, index) { _buildItem(context, index); }
oups, i made a mistake : I wanted to say:
itemBuilder: _buildItem,
And your method should have the 2 parameters : context and index.
how to remove the append list item. I tried on item.removeAt(index); its remove item, but doesnot disapper on screen. Unable to use setState function in Products.dart page