FlutterFlow Docs
Search…
Actions
ListView
The ListView widget is used to show a large number of items as a scrollable list. ListView is an advanced version of the Column widget that automatically provides scrolling when the list of items won't fit on the screen.
You can use the ListView to show the list of items either vertically or horizontally.
ListView

Add a ListView to Your Project

Here's an example of how you can use a ListView widget in your project:
  • First, Drag the ListView widget from the Layout Elements tab (in the Widget Panel)or add it directly from the widget tree.
  • Now add as many Image widgets as you can. Again simply drag it from the Layout Elements tab or add it directly from the widget tree.
To create a ListView widget with custom items:
  • First, Drag the ListView widget from the Layout Elements tab (in the Widget Panel).
  • Now, add the Container widget by dragging it from the same Layout Elements tab or add it directly from the widget tree.
  • Drag and drop the Row widget inside the added Container.
  • Add one Image widget inside the Row.
  • Add the Text widget inside the Row and set its Theme Text Style to Title 1 under the Text Property section from the Property Editor. Also, set its L (Left) padding to 10.
  • Add an IconButton widget, click the default icon Add Box Outlined + under the icon section from the Property Editor, then search and select the chevron_right_sharp icon.
At this point, you have one item added to the list. To fill the ListView with more items simply copy-paste the Container widget. You can also change the image inside the Image widget to make all items look different.
To copy-paste a Container widget:
  • Select the Container widget.
  • Right-click on it and select Copy. You can also use the keyboard shortcut Ctrl+C or Command+C.
  • Select the ListView widget.
  • Right-click on it and select Paste. You can also use the keyboard shortcut Ctrl+V or Command+V.
After adding a number of items the ListView looks like this:

Customizing

The Properties Panel can be used to customize the behavior of your ListView widget.

Add Padding

​Here are the instructions on how to add padding.

Showing Items Horizontally

In the example above you learned how to add items vertically, which is a default axis for laying out children for ListView.
To show items horizontally:
  • Select the ListView from the widget tree or from the canvas area.
  • Move to the Property Editor and scroll down to the ListView Properties section.
  • Spot the Axis dropdown, change it to Horizontal.
In the above visual, the Axis to Horizontal is not properly displaying. In some cases, switching the axis may require you to redesign the item.
To correct the item layout for horizontal direction:
  • Wrap the Row inside the Column by right-clicking on Row, select the Wrap Widget option and then click on Column. You can also select the Row widget and then hit the shortcut (⌘ + B).
  • Drag the Text and IconButton widget outside of Row and put it inside the Column.
  • Set the Text widget's Theme Text Style to Body Text 1.
  • Drag the Row widget up and make it the first child of the Column.
  • Apply this to all items or simply copy-paste the modified item.
The updated item for horizontal layout looks like this:

Shrinking the ListView

By default, the ListView widget takes up all of the available space in its main axis. That means if the Axis property is set to Vertical, ListView will occupy all vertical space on the screen. Similarly, if the Axis is set to Horizontal then ListView will reserve all the horizontal space.
To make the ListView only take the size of its children:
  • Select the ListView from the widget tree or from the canvas area.
  • Move to the Property Editor and scroll down to the ListView Properties section.
  • Checkmark the Shrink Wrap check box.
Below you can see how the Green color selection for ListView shrinks down when Shrink Wrap is checked.

Enable Pull to Refresh

To enable pull to refresh on this widget, please follow the instructions here.

Showing Backend Data

Sometimes you may need to show a list of items from your backend. There are main two sources from where you can get the data.

1. Showing Data from Firestore

You may be using the Firstore to store your app data in the collection-document model. Let's see how you can display the items from the Firestore collection into the ListView.

1.1 Prerequisites

Before we fetch data from Firestore, make sure you incorporate all the mentioned prerequisites to have some data in Firestore.
Your pictures collection with the URL of some images should look like the following:

1.2 Querying a Collection on a ListView

Querying a collection allows you to get a list of documents from inside the collection and show them in the ListView.
To query a collection on a ListView:
  • Select the ListView widget from the widget tree or from the canvas area.
  • Click on the Backend Query tab (on the right side of your screen).
  • Set the Query Type to Query Collection.
  • Scroll down to find the Collection dropdown and change it to your collection.
  • Set the Query Type to List of Documents.
  • Click Save.

1.3 Showing Data in UI Elements

To show an image from URL and Image name stored in your Firestore document:
  • Select the Image Widget from the widget tree or from the canvas area.
  • Move to property editor and scroll down to the path property.
  • Click on the Set from Variable text. (This will open a new panel)
    • Find the Source dropdown, click on unset and select the [collection] Record (from ListView).
    • Under the Available Options, click on Unset and select the field that holds the image URL path.
    • Click Save.
  • Similarly, Select the Text Widget. Move to property editor and set the data for the Text property.
Here's how it looks when you run your app:

2. Showing Data from API call

You may be using your own infrastructure to store your app data. The data can be retrieved via API calls.

2.1 Prerequisites

Before we show data from an API call, make sure you incorporate all the mentioned prerequisites.
If you haven't set up API calls at your backend side yet, you can use any open API for trying it out. Maybe you can try this https://picsum.photos/v2/list​
After adding an API call in FlutterFlow, it looks like this:

2.2 Making API call on a ListView

Making an API call allows you to get a response (containing the list of items) and show them in the ListView.
To make an API call on a ListView:
  • Select the ListView widget from the widget tree or from the canvas area.
  • Click on the Backend Query tab (on the right side of your screen).
  • Set the Query Type to API Call.
  • Set the Call Name to the API Name that fetches the data.
  • Click Save.

2.3 Generating Dynamic Children

Generating dynamic children help you prepare a list of items present in the API response. The returned result is stored in a variable which you can use to populate the ListView.
To generate dynamic children:
  • Select ListView from the widget tree or from the canvas area.
  • Click on the Generate Dynamic Children tab (on the right side of your screen).
  • Enter the appropriate Variable Name.
  • Set the Source value to the [apicall_name] Response (from ListView).
  • Set the Response Options to JSON Body.
  • Under the Available Options, click on Unset and select the JSON Path.
  • Inside the JSON Path, enter the JSON expression to retrieve the list. See how to get JSON Path here.
  • Click Save.

2.4 Showing Data in UI Elements

To show an image from URL and Author name stored inside the variable.
  • Select the Image Widget from the widget tree or from the canvas area.
  • Move to property editor and scroll down to the path property.
  • Click on the Set from Variable text. (This will open a new panel)
    • Find the Source dropdown, click on unset and select the [variable_name] Item (Json).
    • Under the Available Options, click on Unset and select the JSON Path.
    • Inside the JSON Path, enter the JSON expression to retrieve the list. See how to get JSON Path here.
    • Click Save.
  • Similarly, Select the Text Widget. Move to property editor and set the data for the Text property.
Here's how it looks when you run your app:

Adding infinite scroll

The infinite scroll automatically loads the new items as you scroll down the screen. The infinite scrolling works by showing only a limited number of items (e.g. 15, 25) at first and loads subsequent items before the user reaches the end of the list. The circular progress bar is shown at the end of the list while the new items are being loaded.
Infinite scroll
Infinite scroll behind the scene
Adding infinite scroll helps you improve the user experience by reducing the initial waiting time (as without infinite scroll it would take more time to load the long list) and loading new items only when required.
Pro tip
  • Consider adding an infinite scroll if you are going to load the extensive list.
  • Infinite scroll can be only added to the query on ListView.
The infinite scroll can be added to the list of items retrieved from two sources:

Infinite scroll on a list from the Firestore collection

In FlutterFlow, you can directly enable the infinite scroll on a list of items received from the Firestore collection.
To enable the infinite scroll:
  • ​Query a collection on a ListView (skip if you have already done so).
  • Select the ListView, move to the properties panel and select the Backend Query section.
  • Scroll down the already added query and turn on the Enable Infinite Scroll.
  • On enabling the infinite scroll, the Listen For Changes property also gets enabled. That means, the list automatically updates if any changes are made to the item. This is done to keep all the items up to date on the screen. However, it does not update the list if any new item is added or deleted. In rare cases, you would need to disable this feature. To do so, simply turn off this property.
  • In infinite scroll, the items are loaded in chunks called pages. The number of items to load on a single page is determined by the Page Size property. By default, the value is set to 25 (i.e load 25 items per page). The ListView loads the first page as soon as it is visible on the screen and the subsequent pages (with the number of items defined in the Page Size property) are loaded as you scroll down the screen. You can adjust this value as per your design and requirement.
  • Click Save.
Infinite scroll on a list from the Firestore collection

Infinite scroll on a list from API call response

Adding infinite scroll on the list from an API call response is not currently supported in FlutterFlow directly. However, you can add the API call (that supports pagination) in FlutterFlow and extend it to implement the infinite scroll by downloading and modifying the code generated by FlutterFlow.
Adding infinite scroll manually includes:

1. Add paginated API call in FlutterFlow

The paginated API is the API that returns the result in chunks. You can add the paginated API in FlutterFlow by performing the following steps:
  • Select API Calls from the left Navigation Menu.
  • Click Add API Call button.
  • Enter the API Call Name such as getCharacters.
  • Select the Method Type to GET.
  • Enter the API URL. (i.e Paginated API endpoint). Most of the paginated API requires you to add the query parameters to know how many items to retrieve and from where to start.
  • To add the required query parameter, click on the Add Parameter and specify Name, Value Type, and Default Value.
  • Click Save.
Adding paginated API call in FlutterFlow

2. Query API call

This step includes adding the ListView -> ListTile widget and querying the paginated API call. While querying the API call make sure to pass the query parameter.
Query API call

3. Download and modify the code

After adding paginated API, you can download and modify the code. Modifying the code includes using the Infinite scroll pagination package and making changes in the code accordingly.
Here are the steps in detail:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
auto_size_text: 3.0.0
infinite_scroll_pagination: 3.1.0 # <-- SEE HERE
  • Open the page (on which you would like to add infinite scroll) in the editor and make changes in the code as per below:
//get_characters_widgets.dart
​
import 'package:flutter/material.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
​
import '../backend/api_requests/api_calls.dart';
import '../flutter_flow/flutter_flow_icon_button.dart';
import '../flutter_flow/flutter_flow_theme.dart';
import '../flutter_flow/flutter_flow_util.dart';
​
class GetCharactersWidget extends StatefulWidget {
const GetCharactersWidget({Key key}) : super(key: key);
​
@override
_GetCharactersWidgetState createState() => _GetCharactersWidgetState();
}
​
class _GetCharactersWidgetState extends State<GetCharactersWidget> {
final scaffoldKey = GlobalKey<ScaffoldState>();
​
// 1.
static const _pageSize = 20;
final PagingController<int, dynamic> _pagingController =
PagingController(firstPageKey: 0);
​
@override
void initState() {
super.initState();
logFirebaseEvent('screen_view',
parameters: {'screen_name': 'GetCharacters'});
// 2.
_pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
}
​
// 3.
Future<void> _fetchPage(int pageKey) async {
try {
final apiResponse = await GetCharactersCall.call(
offset: pageKey,
limit: _pageSize,
);
final newItems = getJsonField(
(apiResponse?.jsonBody ?? ''),
r'''#x27;'',
)?.toList() ??
[];
final isLastPage = newItems.length < _pageSize;
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
// 3.1 Use this for offset based pagination
final nextPageKey = pageKey + newItems.length;
// 3.2 Use this for page based pagination
//final nextPageKey = ++pageKey;
_pagingController.appendPage(newItems, nextPageKey);
}
} catch (error) {
_pagingController.error = error;
}
}
​
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryColor,
automaticallyImplyLeading: false,
leading: FlutterFlowIconButton(
borderColor: Colors.transparent,
borderRadius: 30,
borderWidth: 1,
buttonSize: 60,
icon: Icon(
Icons.arrow_back_rounded,
color: Colors.white,
size: 30,
),
onPressed: () {
print('IconButton pressed ...');
},
),
title: Text(
'Page Title',
style: FlutterFlowTheme.of(context).title2.override(
fontFamily: 'Roboto',
color: Colors.white,
fontSize: 22,
),
),
actions: [],
centerTitle: false,
elevation: 5,
),
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
// 4.
child: PagedListView<int, dynamic>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<dynamic>(
itemBuilder: (context, item, index) => ListTile(
title: Text(
getJsonField(
item,
r'''$.name''',
).toString(),
style: FlutterFlowTheme.of(context).title3,
),
trailing: Icon(
Icons.arrow_forward_ios,
color: Color(0xFF303030),
size: 20,
),
tileColor: Color(0xFFF5F5F5),
dense: false,
),
),
),
),
),
);
}
​
// 5.
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
}
​
Here’s a quick rundown of what’s going on in the code above:
  1. 1.
    These are the variables that define page size and a paging controller. The paging controller is responsible for driving the whole infinite scroll thing.
  2. 2.
    You are asking the paging controller to load the first page as soon as this widget is visible on the screen.
  3. 3.
    This method makes the API call.
    1. 1.
      If you are using offset-based pagination, use this code.
    2. 2.
      If you are using page-based pagination, use this code.
  4. 4.
    Replace the code to show the ListView (generated by FlutterFlow) with this code. This uses the PagedListView from the library.
  5. 5.
    Finally, dispose the paging controller to free up the memory space.

Adding

Show/Hide ListView

Please find the instructions to show/hide the widget here.
Last modified 3d ago