Created
September 24, 2021 11:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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