Working with Scrollable Widgets
1. Using SingleChildScrollView Widget
| Property | Values | Description |
|---|---|---|
| child | Widget |
The widget to be displayed inside the scrollable area. |
| scrollDirection | Axis.horizontal or Axis.vertical |
Determines the direction of scrolling. Default is Axis.vertical. |
| reverse | true or false |
Reverses the scroll direction. Default is false. |
| controller | ScrollController |
Controls the scrolling behavior of the widget. |
| primary | true or false |
If true, the widget uses the primary scroll controller. Default is false. |
| physics | ScrollPhysics |
Defines how the scrollable widget behaves when scrolled. Default is AlwaysScrollableScrollPhysics. |
Example: Basic usage of SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [
Text('This is a long text that will be scrolled'),
Text('Another line of content'),
Container(
height: 200,
color: Colors.blue,
),
],
),
)
SingleChildScrollView is best used for small content that needs to be scrolled. For large lists, consider using ListView instead.
2. Using ListView Widget
| Property | Values | Description |
|---|---|---|
| children | List<Widget> |
Required list of child widgets to display in the list |
| scrollDirection | Axis.horizontal or Axis.vertical |
Direction of scrolling (default: vertical) |
| reverse | true or false |
Whether to show items in reverse order (default: false) |
| controller | ScrollController |
Controls scrolling behavior and listens to scroll events |
| primary | true or false |
Whether this is the primary scroll view (default: false) |
| physics | ScrollPhysics |
Defines how the list behaves when scrolled (default: AlwaysScrollableScrollPhysics) |
Example: Basic ListView
ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
)
Example: Horizontal ListView
ListView(
scrollDirection: Axis.horizontal,
children: [
Container(width: 100, child: Text('Item 1')),
Container(width: 100, child: Text('Item 2')),
Container(width: 100, child: Text('Item 3')),
],
)
ListView is optimized for lists with a large number of items. For small lists, consider using Column or Row.
3. Using ListView.builder() Method
The ListView.builder() method is a memory-efficient way to create lists with a large number of items. It builds only the widgets that are currently visible on the screen, improving performance.
| Property | Description | Values |
|---|---|---|
| itemCount | Number of items in the list | int |
| itemBuilder | Function that builds each list item | Widget Function(BuildContext, int) |
| scrollDirection | Direction of scrolling | Axis.horizontal or Axis.vertical |
| controller | ScrollController to control scrolling | ScrollController |
Example: Basic ListView.builder()
ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
)
Example: Horizontal ListView.builder()
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: 100,
margin: EdgeInsets.all(8),
child: Text('Card $index'),
);
},
)
4. Using ListView.separated() Method
ListView.separated is a specialized widget in Flutter that creates a list with separators between items. It's particularly useful for creating lists where you want to visually distinguish each item from the next one, such as in a contact list or a settings menu.
| Property | Description | Values |
|---|---|---|
| itemBuilder | Function that builds each list item | (BuildContext context, int index) → Widget |
| separatorBuilder | Function that builds the separator between items | (BuildContext context, int index) → Widget |
| itemCount | Number of items in the list | int |
Example: Basic Usage of ListView.separated()
ListView.separated(
itemCount: 5,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
separatorBuilder: (context, index) {
return Divider();
},
)
separatorBuilder is called once for each separator, and the itemBuilder is called for each item. The total number of widgets created is itemCount * 2 - 1 (items + separators).
Example: Custom Separator with Padding
ListView.separated(
itemCount: 3,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
subtitle: Text('Subtitle for item $index'),
);
},
separatorBuilder: (context, index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Divider(height: 1.0),
);
},
)
5. Using GridView Widget
The GridView widget in Flutter is used to display a scrollable grid of widgets. It's particularly useful for displaying lists of items in a grid layout, such as images or cards.
| Property | Description | Values |
|---|---|---|
| children | List of widgets to display in the grid | List<Widget> |
| gridDelegate | Defines the layout of the grid | SliverGridDelegate |
| scrollDirection | Direction in which the grid scrolls | Axis.horizontal or Axis.vertical |
| scrollController | Controls the scrolling behavior | ScrollController |
Example: Basic GridView
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 10,
itemBuilder: (context, index) {
return Card(
child: Center(
child: Text('Item $index'),
),
);
},
)
Example: GridView with Fixed Cross Axis Count
GridView.count(
crossAxisCount: 3,
children: List.generate(12, (index) {
return Card(
child: Center(
child: Text('Item $index'),
),
);
}),
)
GridView.count constructor is a convenient way to create a grid with a fixed number of columns or rows.
GridView.builder, make sure to use itemCount to define the number of items, otherwise it will throw an error.
Summary of GridView Properties
- gridDelegate: Determines how the grid is laid out
- children: List of widgets to display in the grid
- scrollDirection: Controls the scrolling direction
- scrollController: Manages scroll behavior
6. Using GridView.builder() Method
The GridView.builder() method is a powerful way to create scrollable grids in Flutter, especially when dealing with large datasets. It builds only the visible widgets, improving performance.
| Property | Description | Values |
|---|---|---|
| gridDelegate | Defines the layout of the grid, such as number of columns and spacing. | SliverGridDelegate |
| itemCount | Total number of items in the grid. | int |
| buildItem | Callback function to build each item in the grid. | Widget Function(BuildContext, int) |
Example: Basic GridView.builder()
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
),
itemCount: 20,
itemBuilder: (context, index) {
return Card(
child: Center(
child: Text('Item $index'),
),
);
},
)
GridView.builder() is more efficient than GridView.count() for large lists because it only builds the widgets that are visible on screen.
7. Using GridView.count() Method
The GridView.count() method is used to create a grid layout with a fixed number of columns. It's particularly useful when you want to display items in a uniform grid where the number of columns is known.
| Property | Description | Values |
|---|---|---|
| crossAxisCount | Defines the number of columns in the grid. | int |
| mainAxisSpacing | Defines the spacing between rows. | double |
| crossAxisSpacing | Defines the spacing between columns. | double |
| childAspectRatio | Defines the aspect ratio of each child in the grid. | double |
Example: Basic GridView.count
GridView.count(
crossAxisCount: 3,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
childAspectRatio: 1.0,
children: List.generate(12, (index) {
return Container(
color: Colors.blue[300],
child: Center(
child: Text('Item $index'),
),
);
}),
)
8. Using GridView.extent() Method
The GridView.extent() constructor creates a scrollable grid of widgets with a maximum width for each cell. It's useful when you want to ensure that all grid items have the same maximum width, regardless of their content.
| Property | Description | Values |
|---|---|---|
| maxCrossAxisExtent | Maximum width of each grid item | double |
| children | List of widgets to display in the grid | List<Widget> |
| crossAxisCount | Number of columns in the grid (optional if maxCrossAxisExtent is provided) |
int |
| mainAxisSpacing | Space between rows | double |
| crossAxisSpacing | Space between columns | double |
Example: Using GridView.extent()
GridView.extent(
maxCrossAxisExtent: 150,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: [
Container(
color: Colors.blue,
child: Text('Item 1'),
),
Container(
color: Colors.green,
child: Text('Item 2'),
),
Container(
color: Colors.red,
child: Text('Item 3'),
),
],
)
9. Using PageView Widget
The PageView widget in Flutter is a scrollable container that displays one page at a time, allowing users to swipe between pages. It's particularly useful for creating tutorials, image galleries, or any content that benefits from a paginated layout.
| Property | Description | Values |
|---|---|---|
| controller | Controls the current page and scroll position. | PageController |
| children | List of widgets to display as pages. | List<Widget> |
| scrollDirection | Direction in which the pages scroll. | Axis.horizontal or Axis.vertical |
| reverse | Whether to reverse the scroll direction. | true or false |
| pageSnapping | Whether to snap to full pages during scrolling. | true or false |
| onPageChanged | Callback when the page changes. | Function(int) |
Example: Basic PageView
PageView(
children: [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
)
Example: PageView with Controller
final PageController _controller = PageController();
PageView(
controller: _controller,
children: [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
)
PageView widget is built on top of ListView, so it supports all the same scroll behaviors and properties.
PageView has a defined size or is placed inside a layout that provides one, otherwise it may not render correctly.
10. Using ReorderableListView Widget
The ReorderableListView widget in Flutter allows users to reorder list items by dragging them. It's particularly useful for creating lists where the user can customize the order of elements.
| Property | Description | Values |
|---|---|---|
| children | A list of widgets to display in the reorderable list. | List<Widget> |
| onReorder | Callback function called when an item is reordered. | Function(int oldIndex, int newIndex) |
| buildDraggable | Function to customize how draggable items look. | Function(BuildContext context, int index) |
| header | Optional header widget to display above the list. | Widget |
Example: Basic ReorderableListView
ReorderableListView(
children: [
for (int i = 0; i < 10; i++)
ListTile(
key: Key(i.toString()),
title: Text('Item $i'),
),
],
onReorder: (oldIndex, newIndex) {
// Handle reordering logic here
},
)
ReorderableListView requires each child to have a unique key for proper reordering.
ReorderableListView is not suitable for very large lists due to performance considerations.