flexible_horizontal_list_view 0.1.2
flexible_horizontal_list_view: ^0.1.2 copied to clipboard
A horizontal ListView that doesn't require a fixed height
flexible_horizontal_list_view #
A horizontal ListView that doesn't require a fixed height.
Features #
The HorizontalListView widget is designed as a replacement to the Flutter ListView with scrollDirection: Axis.horizontal.
Each child in the HorizontalListView is being laid out without any constraints, allowing them to determine their "natural" size. This means that the height of the HorizontalListView adjusts to the tallest currently laid out child.
You can also wrap HorizontalListView with a bounded the height (e.g. using a SizedBox) to limit the maximum height of its children.
By setting the flexibleHeight property to true, the height of the HorizontalListView will dynamically adjust to match the height of the currently visible laid out child.
Limitation #
Since children can be laid out without any constraints, widgets like Center or Align will not expand to fill the height of the HorizontalListView. These widgets size themselves based on their child when no height constraint is provided.
If you want them to fill the height, make sure the HorizontalListView has a bounded height, using something like a SizedBox.
- No
itemExtentoritemExtentBuilderproperties
Because each child must be laid out individually to determine its height, the itemExtent and itemExtentBuilder properties are not supported.
Usage #
Like ListView, there are four options for constructing a HorizontalListView:
-
The default constructor takes an explicit
List<Widget>of children. This constructor is appropriate for list views with a small number of children because constructing the List requires doing work for every child that could possibly be displayed in the list view instead of just those children that are actually visible. -
The
HorizontalListView.builderconstructor takes an IndexedWidgetBuilder, which builds the children on demand. This 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 actually visible. -
The
HorizontalListView.separatedconstructor takes two IndexedWidgetBuilders:itemBuilderbuilds child items on demand, andseparatorBuildersimilarly builds separator children which appear in between the child items. This constructor is appropriate for list views with a fixed number of children. -
The
HorizontalListView.customconstructor takes a SliverChildDelegate, which provides the ability to customize additional aspects of the child model. For example, a SliverChildDelegate can control the algorithm used to estimate the size of children that are not actually visible.
To control the initial scroll offset of the scroll view, provide a controller with its ScrollController.initialScrollOffset property set.
By default, HorizontalListView will automatically pad the list's scrollable extremities to avoid partial obstructions indicated by MediaQuery's padding. To avoid this behavior, override with a zero padding property.
If non-null, the prototypeItem forces the children to have the same size as the given widget in the scroll direction.
Specifying an prototypeItem is more efficient than letting the children determine their own size because the scrolling machinery can make use of the foreknowledge of the children's size to save work, for example when the scroll position changes drastically.
This example uses the default constructor for HorizontalListView which takes an explicit List<Widget> of children. This HorizontalListView's children are made up of Containers with Text.

HorizontalListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
width: 200,
color: Colors.amber.shade400,
child: Text(
' Entry A ',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Container(
width: 300,
color: Colors.amber.shade500,
child: Text(
' Entry B ',
style: TextStyle(fontSize: 30),
),
),
Container(
width: 200,
color: Colors.amber.shade600,
child: Text(
' Entry C ',
style: TextStyle(fontSize: 10),
),
),
Container(
width: 350,
color: Colors.amber.shade700,
child: Text(
' Entry D ',
style: TextStyle(fontSize: 50),
),
),
],
)
This example mirrors the previous one, creating the same list using the HorizontalListView.builder constructor. Using the IndexedWidgetBuilder, children are built lazily and can be infinite in number.
final List<String> entries = <String>['A', 'B', 'C', 'D'];
final List<int> colorCodes = <int>[400, 500, 600, 700];
final List<double> widths = <double>[200.0, 300.0, 200.0, 350.0];
final List<double> fontSizes = <double>[20.0, 30.0, 10.0, 50.0];
Widget build(BuildContext context) {
return HorizontalListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (context, index) {
return Container(
width: widths[index],
color: Colors.amber[colorCodes[index]],
child: Text(
' Entry ${entries[index]} ',
style: TextStyle(fontSize: fontSizes[index], fontWeight: FontWeight.bold),
),
);
},
);
}
This example continues to build from our the previous ones, creating a similar list using HorizontalListView.separated. Here, a SizedBox is used as a separator.

final List<String> entries = <String>['A', 'B', 'C', 'D'];
final List<int> colorCodes = <int>[400, 500, 600, 700];
final List<double> widths = <double>[200.0, 300.0, 200.0, 350.0];
final List<double> fontSizes = <double>[20.0, 30.0, 10.0, 50.0];
Widget build(BuildContext context) {
return HorizontalListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (context, index) {
return Container(
width: widths[index],
color: Colors.amber[colorCodes[index]],
child: Text(
' Entry ${entries[index]} ',
style: TextStyle(fontSize: fontSizes[index], fontWeight: FontWeight.bold),
),
);
},
separatorBuilder: (context, index) => SizedBox(width: 10),
);
}
