Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example
94 changes: 52 additions & 42 deletions lib/responsive_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,32 @@ import 'package:flutter/widgets.dart';
class ResponsiveGridView extends StatelessWidget {
final Axis scrollDirection;
final bool reverse;
final ScrollController controller;
final bool primary;
final ScrollPhysics physics;
final ScrollController? controller;
final bool? primary;
final ScrollPhysics? physics;
final bool shrinkWrap;
final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry? padding;

/// Align grid items together as a group.
final AlignmentGeometry alignment;

/// A custom [SliverGridDelegate] with item size control.
final ResponsiveGridDelegate gridDelegate;
final IndexedWidgetBuilder itemBuilder;
final int itemCount;
final int maxRowCount;
final int? itemCount;
final int? maxRowCount;
final bool addAutomaticKeepAlives;
final bool addRepaintBoundaries;
final bool addSemanticIndexes;
final double cacheExtent;
final int semanticChildCount;
final double? cacheExtent;
final int? semanticChildCount;
final DragStartBehavior dragStartBehavior;
final ScrollViewKeyboardDismissBehavior keyboardDismissBehavior;
final Clip clipBehavior;
final String? restorationId;

ResponsiveGridView.builder({
Key key,
Key? key,
this.scrollDirection = Axis.vertical,
this.reverse = false,
this.controller,
Expand All @@ -47,8 +49,8 @@ class ResponsiveGridView extends StatelessWidget {
this.shrinkWrap = false,
this.padding,
this.alignment = Alignment.centerLeft,
@required this.gridDelegate,
@required this.itemBuilder,
required this.gridDelegate,
required this.itemBuilder,
this.itemCount,
this.maxRowCount,
this.addAutomaticKeepAlives = true,
Expand All @@ -58,7 +60,9 @@ class ResponsiveGridView extends StatelessWidget {
this.semanticChildCount,
this.dragStartBehavior = DragStartBehavior.start,
this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
}) : assert(gridDelegate != null);
this.clipBehavior = Clip.hardEdge,
this.restorationId,
});

@override
Widget build(BuildContext context) {
Expand All @@ -69,11 +73,11 @@ class ResponsiveGridView extends StatelessWidget {
// must be preserved for the [BoxScrollView] to calculate
// an effective padding with SafeArea. Create a
// temporary variable here to avoid overwriting null.
EdgeInsets paddingHolder = padding ?? EdgeInsets.zero;
EdgeInsets paddingHolder = padding as EdgeInsets? ?? EdgeInsets.zero;
// The maximum number of items that can fit on one row.
int crossAxisCount;
// The maximum number of items that fit under the max row count.
int maxItemCount;
int? maxItemCount;
// Manual padding adjustment for alignment.
EdgeInsetsGeometry alignmentPadding;
// The width of all items and padding.
Expand All @@ -86,15 +90,16 @@ class ResponsiveGridView extends StatelessWidget {
if (gridDelegate.crossAxisExtent != null) {
// Fixed item size.
crossAxisCount = (crossAxisExtent /
(gridDelegate.crossAxisExtent + gridDelegate.crossAxisSpacing))
(gridDelegate.crossAxisExtent! + gridDelegate.crossAxisSpacing))
.floor();
crossAxisWidth = crossAxisCount *
(gridDelegate.crossAxisExtent + gridDelegate.crossAxisSpacing) +
(gridDelegate.crossAxisExtent! +
gridDelegate.crossAxisSpacing) +
paddingHolder.horizontal;
} else if (gridDelegate.maxCrossAxisExtent != null) {
// Max item size.
crossAxisCount = (crossAxisExtent /
(gridDelegate.maxCrossAxisExtent +
(gridDelegate.maxCrossAxisExtent! +
gridDelegate.crossAxisSpacing))
.ceil();
final double usableCrossAxisExtent = crossAxisExtent -
Expand All @@ -107,7 +112,7 @@ class ResponsiveGridView extends StatelessWidget {
} else {
// Min item size.
crossAxisCount = (crossAxisExtent /
(gridDelegate.minCrossAxisExtent +
(gridDelegate.minCrossAxisExtent! +
gridDelegate.crossAxisSpacing))
.floor();
final double usableCrossAxisExtent = crossAxisExtent -
Expand Down Expand Up @@ -155,7 +160,7 @@ class ResponsiveGridView extends StatelessWidget {
}
// Force row limit by calculating item limit.
if (maxRowCount != null) {
maxItemCount = maxRowCount * crossAxisCount;
maxItemCount = maxRowCount! * crossAxisCount;
}
// Internal children builder delegate.
SliverChildDelegate childrenDelegate = SliverChildBuilderDelegate(
Expand All @@ -181,6 +186,8 @@ class ResponsiveGridView extends StatelessWidget {
semanticChildCount: semanticChildCount,
dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior,
clipBehavior: clipBehavior,
restorationId: restorationId,
),
);
});
Expand All @@ -191,27 +198,28 @@ class ResponsiveGridView extends StatelessWidget {
class _ResponsiveGridViewLayout extends BoxScrollView {
final ResponsiveGridDelegate gridDelegate;
final SliverChildDelegate childrenDelegate;
final int itemCount;
final int? itemCount;

_ResponsiveGridViewLayout({
Key key,
Key? key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
ScrollController? controller,
bool? primary,
ScrollPhysics? physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required this.gridDelegate,
@required this.childrenDelegate,
EdgeInsetsGeometry? padding,
required this.gridDelegate,
required this.childrenDelegate,
this.itemCount,
double cacheExtent,
int semanticChildCount,
double? cacheExtent,
int? semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior =
ScrollViewKeyboardDismissBehavior.manual,
}) : assert(gridDelegate != null),
super(
String? restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : super(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
Expand All @@ -224,6 +232,8 @@ class _ResponsiveGridViewLayout extends BoxScrollView {
semanticChildCount: semanticChildCount ?? itemCount,
dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId,
clipBehavior: clipBehavior,
);

@override
Expand Down Expand Up @@ -254,18 +264,18 @@ class ResponsiveGridDelegate extends SliverGridDelegate {
(maxCrossAxisExtent != null && maxCrossAxisExtent >= 0) ||
(minCrossAxisExtent != null && minCrossAxisExtent >= 0),
'Must provide a valid cross axis extent.'),
assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
assert(childAspectRatio != null && childAspectRatio > 0);
assert(mainAxisSpacing >= 0),
assert(crossAxisSpacing >= 0),
assert(childAspectRatio > 0);

/// Fixed item size.
final double crossAxisExtent;
final double? crossAxisExtent;

/// Maximum item size.
final double maxCrossAxisExtent;
final double? maxCrossAxisExtent;

/// Minimum item size.
final double minCrossAxisExtent;
final double? minCrossAxisExtent;
final double mainAxisSpacing;
final double crossAxisSpacing;
final double childAspectRatio;
Expand All @@ -290,19 +300,19 @@ class ResponsiveGridDelegate extends SliverGridDelegate {
// Item height.
double childMainAxisExtent;
// Item width.
double childCrossAxisExtent;
double? childCrossAxisExtent;
// Switch between item sizing behaviors.
if (this.crossAxisExtent != null) {
crossAxisCount =
(constraints.crossAxisExtent / (crossAxisExtent + crossAxisSpacing))
(constraints.crossAxisExtent / (crossAxisExtent! + crossAxisSpacing))
.floor();
childCrossAxisExtent = crossAxisExtent;
childMainAxisExtent = childCrossAxisExtent / childAspectRatio;
childMainAxisExtent = childCrossAxisExtent! / childAspectRatio;
mainAxisStride = childMainAxisExtent + mainAxisSpacing;
crossAxisStride = childCrossAxisExtent + crossAxisSpacing;
} else if (this.maxCrossAxisExtent != null) {
crossAxisCount = (constraints.crossAxisExtent /
(maxCrossAxisExtent + crossAxisSpacing))
(maxCrossAxisExtent! + crossAxisSpacing))
.ceil();
final double usableCrossAxisExtent =
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
Expand All @@ -312,7 +322,7 @@ class ResponsiveGridDelegate extends SliverGridDelegate {
crossAxisStride = childCrossAxisExtent + crossAxisSpacing;
} else {
crossAxisCount = (constraints.crossAxisExtent /
(minCrossAxisExtent + crossAxisSpacing))
(minCrossAxisExtent! + crossAxisSpacing))
.floor();
final double usableCrossAxisExtent =
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
Expand Down
46 changes: 23 additions & 23 deletions lib/responsive_row_column.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@ class ResponsiveRowColumn extends StatelessWidget {
final MainAxisAlignment rowMainAxisAlignment;
final MainAxisSize rowMainAxisSize;
final CrossAxisAlignment rowCrossAxisAlignment;
final TextDirection rowTextDirection;
final TextDirection? rowTextDirection;
final VerticalDirection rowVerticalDirection;
final TextBaseline rowTextBaseline;
final TextBaseline? rowTextBaseline;
final MainAxisAlignment columnMainAxisAlignment;
final MainAxisSize columnMainAxisSize;
final CrossAxisAlignment columnCrossAxisAlignment;
final TextDirection columnTextDirection;
final TextDirection? columnTextDirection;
final VerticalDirection columnVerticalDirection;
final TextBaseline columnTextBaseline;
final double rowSpacing;
final double columnSpacing;
final TextBaseline? columnTextBaseline;
final double? rowSpacing;
final double? columnSpacing;
final EdgeInsets rowPadding;
final EdgeInsets columnPadding;
get isRow => rowColumn;
get isColumn => !rowColumn;

const ResponsiveRowColumn(
{Key key,
{Key? key,
this.children = const [],
@required this.rowColumn,
required this.rowColumn,
this.rowMainAxisAlignment = MainAxisAlignment.start,
this.rowMainAxisSize = MainAxisSize.max,
this.rowCrossAxisAlignment = CrossAxisAlignment.center,
Expand Down Expand Up @@ -96,7 +96,7 @@ class ResponsiveRowColumn extends StatelessWidget {

/// Logic to construct widget [children].
List<Widget> buildChildren(
List<ResponsiveRowColumnItem> children, bool rowColumn, double spacing) {
List<ResponsiveRowColumnItem> children, bool rowColumn, double? spacing) {
// Sort ResponsiveRowColumnItems by their order.
List<ResponsiveRowColumnItem> childrenHolder = children;
childrenHolder.sort((a, b) {
Expand Down Expand Up @@ -135,14 +135,14 @@ class ResponsiveRowColumnItem extends StatelessWidget {
final int rowOrder;
final int columnOrder;
final bool rowColumn;
final int rowFlex;
final int columnFlex;
final FlexFit rowFit;
final FlexFit columnFit;
final int? rowFlex;
final int? columnFlex;
final FlexFit? rowFit;
final FlexFit? columnFit;

const ResponsiveRowColumnItem(
{Key key,
@required this.child,
{Key? key,
required this.child,
this.rowOrder = 1073741823,
this.columnOrder = 1073741823,
this.rowColumn = true,
Expand All @@ -166,14 +166,14 @@ class ResponsiveRowColumnItem extends StatelessWidget {
}

ResponsiveRowColumnItem copyWith({
Widget child,
int rowOrder,
int columnOrder,
bool rowColumn,
int rowFlex,
int columnFlex,
FlexFit rowFlexFit,
FlexFit columnFlexFit,
Widget? child,
int? rowOrder,
int? columnOrder,
bool? rowColumn,
int? rowFlex,
int? columnFlex,
FlexFit? rowFlexFit,
FlexFit? columnFlexFit,
}) =>
ResponsiveRowColumnItem(
child: child ?? this.child,
Expand Down
Loading