Last active
March 20, 2024 19:44
-
-
Save jonathanduke/c09640adacacdff649ebfa0436e5a055 to your computer and use it in GitHub Desktop.
ValueListenableBuilder that wraps an Offstage widget and exposes whether it will be offstage before building completes
This file contains 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/material.dart'; | |
typedef OffstageEvaluator<T> = bool Function(T value); | |
class OffstageValueListenableBuilder<T> extends ValueListenableBuilder<T> { | |
final Key? offstageKey; | |
final OffstageEvaluator<T> offstageEvaluator; | |
OffstageValueListenableBuilder({ | |
super.key, | |
this.offstageKey, | |
required this.offstageEvaluator, | |
required super.valueListenable, | |
required ValueWidgetBuilder<T> builder, | |
super.child, | |
}) : super( | |
builder: (context, value, child) => _buildOffstage( | |
context, | |
offstageKey, | |
offstageEvaluator, | |
value, | |
builder, | |
child, | |
)); | |
bool get offstage => offstageEvaluator(valueListenable.value); | |
static Widget _buildOffstage<T>( | |
BuildContext context, | |
Key? offstageKey, | |
OffstageEvaluator<T> offstageEvaluator, | |
T value, | |
ValueWidgetBuilder<T> builder, | |
Widget? child, | |
) { | |
final offstage = offstageEvaluator(value); | |
return Offstage( | |
key: offstageKey, | |
offstage: offstage, | |
child: builder(context, value, child), | |
); | |
} | |
} |
This file contains 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/material.dart"; | |
import "offstage_value_listenable_builder.dart"; | |
class SpacedListView extends StatelessWidget { | |
final double spacing; | |
final List<Widget> children; | |
const SpacedListView({ | |
super.key, | |
required this.spacing, | |
required this.children, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return ListView.separated( | |
itemBuilder: (context, index) => children[index], | |
separatorBuilder: (context, index) => | |
_buildSeparator(context, spacing, children[index + 1]), | |
itemCount: children.length, | |
); | |
} | |
Widget _buildSeparator(BuildContext context, double spacing, Widget widget) { | |
if (widget is OffstageValueListenableBuilder) { | |
return ValueListenableBuilder( | |
valueListenable: widget.valueListenable, | |
builder: (context, value, child) => widget.offstage | |
? const SizedBox.shrink() | |
: SizedBox(height: spacing), | |
); | |
} else if (widget is Offstage && widget.offstage) { | |
return const SizedBox.shrink(); | |
} | |
return SizedBox(height: spacing); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment