Skip to content

Instantly share code, notes, and snippets.

@nxcco
Created September 24, 2021 11:04
Show Gist options
  • Save nxcco/ee28c7b3e794d86fe435339957e8da56 to your computer and use it in GitHub Desktop.
Save nxcco/ee28c7b3e794d86fe435339957e8da56 to your computer and use it in GitHub Desktop.
This code snippets provide a delegate to build separators in a SliverList. Original code from https://github.com/BreX900/easy_widget. I rewrote it, so that it's null-safety conform.
import 'package:flutter/widgets.dart';
class SliverLayoutDelegate extends SliverChildBuilderDelegate {
SliverLayoutDelegate({
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
SemanticIndexCallback? semanticIndexCallback,
int semanticIndexOffset = 0,
required int childCount,
bool surround: false,
IndexedWidgetBuilder? separatorBuilder,
required IndexedWidgetBuilder builder,
}) : super(
(separatorBuilder == null
? builder
: WidgetBuilderUtility.builderWithSeparator(
builder,
separatorBuilder,
surround: surround,
)),
childCount: WidgetBuilderUtility.childCount(
childCount,
separatorBuilder != null,
surround: surround,
),
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
semanticIndexCallback: (Widget _, int localIndex) => localIndex,
semanticIndexOffset: semanticIndexOffset,
);
factory SliverLayoutDelegate.childrenBuilder({
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
SemanticIndexCallback? semanticIndexCallback,
int semanticIndexOffset = 0,
bool surround: false,
required int childCount,
required Widget separator,
required IndexedWidgetBuilder builder,
}) {
return SliverLayoutDelegate(
surround: surround,
childCount: childCount,
separatorBuilder: (_, __) => separator,
builder: builder,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
semanticIndexCallback: (Widget _, int localIndex) => localIndex,
semanticIndexOffset: semanticIndexOffset,
);
}
factory SliverLayoutDelegate.children({
bool surround: false,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
SemanticIndexCallback? semanticIndexCallback,
int semanticIndexOffset = 0,
Widget? separator,
required List<Widget> children,
}) {
return SliverLayoutDelegate(
surround: surround,
builder: (context, index) => children[index],
childCount: children.length,
separatorBuilder:
separator == null ? (_, __) => SizedBox() : (_, __) => separator,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
semanticIndexCallback: (Widget _, int localIndex) => localIndex,
semanticIndexOffset: semanticIndexOffset,
);
}
}
class ListUtility {
static List<E> joiner<E>(List<E> list, E builder(int index)) {
if (list.length == 1) return list.toList();
final length = (list.length * 2) - 1;
// ignore: deprecated_member_use
final newList = <E>[]..length = length;
for (int i = 0; i < (list.length - 1); i++) {
final index = i * 2;
newList
..[index] = list[i]
..[index + 1] = builder(i);
}
return newList..[length - 1] = list.last;
}
static List<E> nullGenerator<E>(E builder(int index), {int? itemCount}) {
if (itemCount != null) return List.generate(itemCount, builder);
E element = builder(0);
if (element == null) return <E>[];
List<E> newList = <E>[element];
for (int i = 1; element != null; i++) {
newList..add(element);
element = builder(i);
}
return newList;
}
}
class WidgetBuilderUtility {
static IndexedWidgetBuilder builderWithSeparator(
IndexedWidgetBuilder builder, IndexedWidgetBuilder separatorBuilder,
{bool surround: false}) {
if (separatorBuilder == null) return builder;
return (context, index) {
final itemIndex = index ~/ 2;
if (surround ? !(index % 2 == 0) : (index % 2 == 0))
return builder(context, itemIndex);
else
return separatorBuilder(context, itemIndex);
};
}
static int separatorCount(int childCount, [bool surround = false]) {
return childCount > 0
? ((childCount > 1 ? childCount - 1 : 0) + (surround ? 2 : 0))
: 0;
}
static int childCount(int childCount, bool existSeparator,
{bool surround: false}) {
return childCount +
(existSeparator ? separatorCount(childCount, surround) : 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment