Last active
April 13, 2025 09:48
Revisions
-
lukepighetti revised this gist
Mar 1, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -123,8 +123,8 @@ class AnimatedGridDetails { @required this.index, @required this.columnIndex, @required this.rowIndex, @required this.columns, @required this.rows, }); /// The current index -
lukepighetti revised this gist
Mar 1, 2021 . 1 changed file with 41 additions and 5 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import '../extensions/extensions.dart'; typedef AnimatedGridBuilder<T> = Widget Function( BuildContext, T item, AnimatedGridDetails details); class AnimatedGrid<T> extends StatelessWidget { /// An animated grid the animates when the items change sort. @@ -39,11 +39,11 @@ class AnimatedGrid<T> extends StatelessWidget { /// The curve of the sort animation. final Curve curve; static int _rows(int columns, int count) => (count / columns).ceil(); @visibleForTesting static List<int> gridIndicies(int index, int columns, int count) { final rows = _rows(columns, count); final maxItemsForGridSize = columns * rows; final xIndex = (index / maxItemsForGridSize * columns).floor(); final yIndex = index % rows; @@ -94,7 +94,17 @@ class AnimatedGrid<T> extends StatelessWidget { child: SizedBox( height: itemHeight, width: itemWidth, child: builder( context, item, AnimatedGridDetails( index: i, columnIndex: xIndex, rowIndex: yIndex, columns: columns, rows: rows, ), ), ), ); }, @@ -106,3 +116,29 @@ class AnimatedGrid<T> extends StatelessWidget { ); } } class AnimatedGridDetails { /// A collection of details currently being used by [AnimatedGrid] AnimatedGridDetails({ @required this.index, @required this.columnIndex, @required this.rowIndex, @required this.rows, @required this.columns, }); /// The current index final int index; /// The current column index final int columnIndex; /// The current row index final int rowIndex; /// The number of columns final int columns; /// The number of rows final int rows; } -
lukepighetti revised this gist
Mar 1, 2021 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,8 @@ extension IterableX<T> on Iterable<T> { /// The last index on this iterable. /// /// Ie `[A,B,C].lastIndex == 2` int get lastIndex => length == 0 ? throw RangeError('Cannot find the last index of an empty iterable') : length - 1; } -
lukepighetti revised this gist
Mar 1, 2021 . 1 changed file with 6 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import '../extensions/extensions.dart'; typedef AnimatedGridBuilder<T> = Widget Function( BuildContext, T item, int columnIndex, int rowIndex); class AnimatedGrid<T> extends StatelessWidget { /// An animated grid the animates when the items change sort. const AnimatedGrid({ @@ -18,10 +21,11 @@ class AnimatedGrid<T> extends StatelessWidget { /// The grid items. Should all be the same height. final List<T> items; /// Construct keys given the item provided. Each key must be unique. final Key Function(T item) keyBuilder; /// Build a widget given a context, the current item, and the column and row index. final AnimatedGridBuilder<T> builder; /// The number of columns wide to display. final int columns; -
lukepighetti created this gist
Mar 1, 2021 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,104 @@ import 'package:flutter/material.dart'; import '../extensions/extensions.dart'; class AnimatedGrid<T> extends StatelessWidget { /// An animated grid the animates when the items change sort. const AnimatedGrid({ Key key, @required this.itemHeight, @required this.items, @required this.keyBuilder, @required this.builder, this.columns = 2, this.duration = const Duration(milliseconds: 750), this.curve = Curves.elasticOut, }) : super(key: key); /// The grid items. Should all be the same height. final List<T> items; final Key Function(T item) keyBuilder; final Widget Function(BuildContext, T item, int columIndex, int rowIndex) builder; /// The number of columns wide to display. final int columns; /// The height of each child. final double itemHeight; /// The duration of the sort animation. final Duration duration; /// The curve of the sort animation. final Curve curve; static int _rows(int columns, int items) => (items / columns).ceil(); @visibleForTesting static List<int> gridIndicies(int index, int columns, int items) { final rows = _rows(columns, items); final maxItemsForGridSize = columns * rows; final xIndex = (index / maxItemsForGridSize * columns).floor(); final yIndex = index % rows; return [xIndex, yIndex]; } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { assert(constraints.hasBoundedWidth); assert(constraints.hasBoundedHeight == false); final width = constraints.maxWidth; final count = items.length; final itemWidth = width / columns; final rows = _rows(columns, count); final gridHeight = rows * itemHeight; return SizedBox( height: gridHeight, child: Stack( alignment: Alignment.topLeft, children: [ for (var i = 0; i <= items.lastIndex; i++) Builder( key: keyBuilder(items[i]), builder: (context) { final item = items[i]; final indicies = gridIndicies(i, columns, count); assert(indicies.length == 2); final xIndex = indicies.first; final yIndex = indicies.last; final offset = Offset(xIndex * itemWidth, yIndex * itemHeight); return TweenAnimationBuilder( tween: Tween<Offset>(end: offset), duration: duration, curve: curve, builder: (context, offset, child) { return Transform.translate( offset: offset, child: child, ); }, child: SizedBox( height: itemHeight, width: itemWidth, child: builder(context, item, xIndex, yIndex), ), ); }, ), ], ), ); }, ); } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,82 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:vgl/widgets/animated_grid.dart'; main() { group('AnimatedGrid', () { test('gridIndicies', () { /// index 0 /// /// ``` /// 0 2 /// 1 /// ``` expect( AnimatedGrid.gridIndicies(0, 2, 3), equals([0, 0]), ); /// index 2 /// /// ``` /// 0 2 /// 1 /// ``` expect( AnimatedGrid.gridIndicies(2, 2, 3), equals([1, 0]), ); /// index 9 /// /// ``` /// 0 4 8 /// 1 5 9 /// 2 6 /// 3 7 /// ``` expect( AnimatedGrid.gridIndicies(9, 3, 10), equals([2, 1]), ); /// index 7 /// /// ``` /// 0 4 8 /// 1 5 9 /// 2 6 /// 3 7 /// ``` expect( AnimatedGrid.gridIndicies(7, 3, 10), equals([1, 3]), ); /// index 6 /// /// ``` /// 0 4 8 /// 1 5 9 /// 2 6 /// 3 7 /// ``` expect( AnimatedGrid.gridIndicies(6, 3, 10), equals([1, 2]), ); /// index 3 /// /// ``` /// 0 4 8 /// 1 5 9 /// 2 6 /// 3 7 /// ``` expect( AnimatedGrid.gridIndicies(3, 3, 10), equals([0, 3]), ); }); }); }