chained_list 0.9.0
chained_list: ^0.9.0 copied to clipboard
Library for Flutter List tiles with visual connection. Provides convenient way of lists with leading 'metro-lines' widget.
Chained List: Timelines and Step-by-Step Lists in Flutter #
A Flutter library that simplifies building vertical lists with visually connected items, such as timelines, process trackers, or step-by-step guides.
| Circles and IconData | Custom Icons | Complex lines |
|---|---|---|
![]() |
Supports different lines\indicator styles.
Installing #
Add the following to your pubspec.yaml file:
dependencies:
chained_list: ^<latest_version>
Then run flutter pub get.
Usage #
The library provides a specialized "leading" widget that renders an indicator (circle/icon) with vertical connection lines.
There are two ways to implement this:
- High-Level Tiles: Use
ChainedTileorDoubleChainedTilefor automatic layout. - Low-Level Indicator: Use
ChainedIndicatordirectly if you need full control over placement (requires manual sizing).
ChainedTile #
Use this when the line style above and below the indicator is the same. It automatically handles the top and bottom lines for the first and last items.
const ChainedTile(
final Widget child; // main list item content
final int tileIndex; // used to draw properly the first
final int totalCount; // and the last items lines
final ChainLineStyle lineStyle; // line styling
final CircleIndicatorStyle? circleStyle; // circle decoration property
final IconIndicatorStyle? iconStyle; // custom icon can be IconData or Widget
this.indicatorWidth = 50.0, // width of the leading item
);
DoubleChainedTile #
Use this when you need different styles for the top and bottom lines within a single tile (e.g., a "completed" step connecting to an "in-progress" step).
class DoubleChainedTile extends StatefulWidget {
final Widget child; // main list item content
final ChainLineStyle? topLineStyle; // separate styles for top
final ChainLineStyle? bottomLineStyle; // and bottom lines
final CircleIndicatorStyle? circleStyle; // circle decoration property
final IconIndicatorStyle? iconStyle; // custom icon can be IconData or Widget
this.indicatorWidth = 50.0, // width of the leading item
}
ChainedIndicator #
Direct usage of ChainedIndicator gives more control of indicator placement and sizing. But this widget should be placed in parent widget with concrete height and width sizes.
class ChainedIndicator extends StatelessWidget {
final double indicatorWidth; // Horizontal size of the indicator widget
final ChainLineStyle? topLineStyle; // The top part of connection line
final ChainLineStyle? bottomLineStyle; // The bottom part of connection line
final CircleIndicatorStyle? circleStyle; // If set - defines circle indicator drawing style
final IconIndicatorStyle? iconStyle; // If set - defines custom icon style
final double verticalOffset; // Used for dash-pattern synchronization
}
TailData #
Also for easier library usage it is possible to take TailData helper class.
TailData {
final double indicatorWidth; /// Horizontal size of the indicator widget
final ChainLineStyle lineStyle; /// The style of connection line
final IconIndicatorStyle? iconStyle; /// If set - defines custom icon style
}
This class is helpful to process items as center icon + bottom line.
So, for the first item in the list there will be to upper tail, just lower one. A middle item will have both center icon and tail and the last one will have only center icon without line. As always, indicatorWidth represents with of all items and should be bigger then centered icon.
Usage #
As TailData is simple data-class, it cannot be directly used in widget tree. There is helper convertToTiles() function which converts it to properly configured ChainedIndicator list.
As real ChainedIndicator item depends on two subsequental items of TailData, to use convertToTiles user need to pass all items while mapping one TailData to ChainedIndicator:
for (var i = 0; i < tailedItems.length; i++) {
final item = tailedItems[i];
resultList.add(
item.convertToTiles(
index: i,
allTails: tailedItems,
child: getByIndex(i),
),
);
}
or use .mapIndexed() from the collection library.
Pro-Tip: Vertical Synchronization
The verticalOffset property is crucial for dashed lines. Since list items often have different heights, the dash pattern might "break" between tiles. Passing the cumulative height/offset ensures the dashes connect smoothly from one tile to the next.
Future plans #
Left/Right setting
Contributing #
Contributions are welcome! If you find a bug or have a feature request, please open an issue on the GitHub repository.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
