buildListView<T, K> method
Widget
buildListView<T, K>({
- required BuildContext context,
- required List<
TListItem< items,T, K> > - required ListItemBuilder<
T, K> itemBuilder, - required AnimationController animationController,
- required ScrollController scrollController,
- required ScrollController horizontalScrollController,
- required TListController<
T, K> listController, - required TListInteraction<
T> interaction, - required bool loading,
- required bool hasError,
- required TListError? error,
- required bool hasMoreItems,
- double? height,
Implementation
Widget buildListView<T, K>({
required BuildContext context,
required List<TListItem<T, K>> items,
required ListItemBuilder<T, K> itemBuilder,
required AnimationController animationController,
required ScrollController scrollController,
required ScrollController horizontalScrollController,
required TListController<T, K> listController,
required TListInteraction<T> interaction,
required bool loading,
required bool hasError,
required TListError? error,
required bool hasMoreItems,
double? height,
}) {
final effectiveInfiniteScroll = infiniteScroll == true && listController.hasMoreItems;
// Error state takes priority
if (hasError && error != null && items.isEmpty) {
return buildErrorState(context, error);
}
// Empty state when no items and not loading
if (items.isEmpty && !loading) {
return buildEmptyState(context);
}
Widget buildItem(BuildContext context, int index) {
// Header (non-sticky)
if (headerWidget != null && headerSticky != true && index == 0) {
return headerWidget!;
}
// Calculate item index offset
final itemOffset = (headerWidget != null && headerSticky != true) ? 1 : 0;
final itemIndex = index - itemOffset;
// Infinite scroll indicator
final infiniteScrollIndex = items.length + itemOffset;
if (effectiveInfiniteScroll && index == infiniteScrollIndex) {
return _buildInfiniteScrollFooter(context, items, loading, hasMoreItems);
}
// Footer (non-sticky)
final footerIndex = items.length + itemOffset + (effectiveInfiniteScroll ? 1 : 0);
if (footerWidget != null && footerSticky != true && index == footerIndex) {
return footerWidget!;
}
// Regular item
final item = items[itemIndex];
Widget child = interaction.buildGestureDetector(
key: ObjectKey(item),
item: item.data,
index: itemIndex,
selectable: listController.selectable,
expandable: listController.expandable,
controller: listController,
child: itemBuilder(context, item, itemIndex, listController.isMultiSelect),
);
// Apply animation
if (animationBuilder != null) {
child = animationBuilder!(context, animationController, child, itemIndex);
}
// Add spacing
if (itemSpacing > 0) {
child = Padding(
padding: EdgeInsets.only(bottom: itemSpacing),
child: child,
);
}
return child;
}
final totalItemCount = items.length +
(headerWidget != null && headerSticky != true ? 1 : 0) +
(footerWidget != null && footerSticky != true ? 1 : 0) +
(effectiveInfiniteScroll ? 1 : 0);
final effectivePhysics = physics ?? (shrinkWrap ? const NeverScrollableScrollPhysics() : const AlwaysScrollableScrollPhysics());
Widget listView;
if (showSeparators && separatorBuilder != null) {
listView = ListView.separated(
controller: shrinkWrap ? null : scrollController,
shrinkWrap: shrinkWrap,
physics: effectivePhysics,
padding: padding,
itemCount: totalItemCount,
itemBuilder: buildItem,
separatorBuilder: separatorBuilder!,
);
} else {
listView = ListView.builder(
controller: shrinkWrap ? null : scrollController,
shrinkWrap: shrinkWrap,
physics: effectivePhysics,
padding: padding,
itemCount: totalItemCount,
itemBuilder: buildItem,
);
}
// Build column with sticky elements
final column = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (loading && items.isEmpty) buildLoadingIndicator(context),
if (headerWidget != null && headerSticky == true) headerWidget!,
if (shrinkWrap) listView else if (height != null) SizedBox(height: height, child: listView) else Expanded(child: listView),
if (footerWidget != null && footerSticky == true) footerWidget!,
],
);
// Wrap with horizontal scroll if needed
final scrollableContent = needsHorizontalScroll ? _buildHorizontalScroll(column, horizontalScrollController) : column;
return scrollableContent;
}