Skip to content

Commit

Permalink
Merge pull request #218 from letsar/feature/aligned_grid
Browse files Browse the repository at this point in the history
Adding AlignedGrid
  • Loading branch information
letsar committed Jan 1, 2022
2 parents c2d61c1 + 1e7eddf commit ebd911a
Show file tree
Hide file tree
Showing 27 changed files with 1,465 additions and 164 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.6.0
### Added
* SliverAlignedGrid and AlignedGridView widgets.
### Changed
* Renamed SliverMasonryGridDelegate to SliverSimpleGridDelegate.

## 0.5.1
### Added
* StaggeredTile.fit constructor.
Expand Down
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ GridView.custom(
);
```


### **Staired**
![Staired Grid Layout][staired_preview]

Expand Down Expand Up @@ -253,6 +252,41 @@ GridView.custom(
);
```

### **Aligned**
![Aligned Grid Layout][aligned_preview]

This layout is also called CSS Grid. This is a common grid layout on the web, where each item within a track has the maximum cross axis extent of its siblings.

#### **Grid properties**
- Evenly divided in *n* columns
- The rows can have differents heights

#### **Tile properties**
- Must occupy 1 column only
- Each tile has the same height as the tallest one of the row.

#### **Placement algorithm**
- Top-most and then left-most

#### **Example**
Below you'll find the code to create this grid layout:

![Aligned example][aligned_example]

```dart
AlignedGridView.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 7 + 1) * 30,
);
},
);
```

## Sponsoring

I'm working on my packages on my free-time, but I don't have as much time as I would. If this package or any other package I created is helping you, please consider to sponsor me so that I can take time to read the issues, fix bugs, merge pull requests and add features to these packages.
Expand Down Expand Up @@ -292,8 +326,10 @@ If you fixed a bug or implemented a feature, please send a [pull request][pr].
[quilted_preview]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/quilted.png
[woven_preview]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/woven.png
[staired_preview]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/staired.png
[aligned_preview]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/aligned.png
[staggered_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/staggered_example.png
[masonry_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/masonry_example.png
[quilted_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/quilted_example.png
[woven_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/woven_example.png
[staired_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/staired_example.png
[staired_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/staired_example.png
[aligned_example]: https://raw.githubusercontent.com/letsar/flutter_staggered_grid_view/master/docs/images/aligned_example.png
Binary file added docs/images/aligned.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/aligned_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/assets/aligned.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 46 additions & 1 deletion examples/lib/common.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';

const _defaultColor = Color(0xFF34568B);

class AppScaffold extends StatelessWidget {
const AppScaffold({
Key? key,
Expand Down Expand Up @@ -31,17 +33,19 @@ class Tile extends StatelessWidget {
Key? key,
required this.index,
this.extent,
this.backgroundColor,
this.bottomSpace,
}) : super(key: key);

final int index;
final double? extent;
final double? bottomSpace;
final Color? backgroundColor;

@override
Widget build(BuildContext context) {
final child = Container(
color: const Color(0xFF34568B),
color: backgroundColor ?? _defaultColor,
height: extent,
child: Center(
child: CircleAvatar(
Expand Down Expand Up @@ -92,3 +96,44 @@ class ImageTile extends StatelessWidget {
);
}
}

class InteractiveTile extends StatefulWidget {
const InteractiveTile({
Key? key,
required this.index,
this.extent,
this.bottomSpace,
}) : super(key: key);

final int index;
final double? extent;
final double? bottomSpace;

@override
_InteractiveTileState createState() => _InteractiveTileState();
}

class _InteractiveTileState extends State<InteractiveTile> {
Color color = _defaultColor;

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
if (color == _defaultColor) {
color = Colors.red;
} else {
color = _defaultColor;
}
});
},
child: Tile(
index: widget.index,
extent: widget.extent,
backgroundColor: color,
bottomSpace: widget.bottomSpace,
),
);
}
}
27 changes: 27 additions & 0 deletions examples/lib/examples/aligned.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:examples/common.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';

class AlignedPage extends StatelessWidget {
const AlignedPage({
Key? key,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return AppScaffold(
title: 'Aligned',
child: AlignedGridView.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 7 + 1) * 30,
);
},
),
);
}
}
6 changes: 6 additions & 0 deletions examples/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:examples/common.dart';
import 'package:examples/pages/aligned.dart';
import 'package:examples/pages/masonry.dart';
import 'package:examples/pages/quilted.dart';
import 'package:examples/pages/staggered.dart';
Expand Down Expand Up @@ -66,6 +67,11 @@ class HomePage extends StatelessWidget {
imageName: 'staired',
destination: StairedPage(),
),
MenuEntry(
title: 'Aligned',
imageName: 'aligned',
destination: AlignedPage(),
),
],
),
);
Expand Down
6 changes: 6 additions & 0 deletions examples/lib/main_examples.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:examples/common.dart';
import 'package:examples/examples/aligned.dart';
import 'package:examples/examples/masonry.dart';
import 'package:examples/examples/quilted.dart';
import 'package:examples/examples/staggered.dart';
Expand Down Expand Up @@ -66,6 +67,11 @@ class HomePage extends StatelessWidget {
imageName: 'staired',
destination: StairedPage(),
),
MenuEntry(
title: 'Aligned',
imageName: 'aligned',
destination: AlignedPage(),
),
],
),
);
Expand Down
48 changes: 48 additions & 0 deletions examples/lib/pages/aligned.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'dart:math';

import 'package:examples/common.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';

class AlignedPage extends StatefulWidget {
const AlignedPage({
Key? key,
}) : super(key: key);

@override
State<AlignedPage> createState() => _AlignedPageState();
}

class _AlignedPageState extends State<AlignedPage> {
final rnd = Random();
late List<int> extents;
int crossAxisCount = 4;

@override
void initState() {
super.initState();
extents = List<int>.generate(10000, (int index) => rnd.nextInt(7) + 1);
}

@override
Widget build(BuildContext context) {
return AppScaffold(
title: 'Aligned',
child: AlignedGridView.count(
crossAxisCount: crossAxisCount,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
final height = extents[index] * 40;
return ImageTile(
index: index,
width: 100,
height: height,
);
},
itemCount: extents.length,
),
);
}
}
3 changes: 3 additions & 0 deletions lib/flutter_staggered_grid_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ export 'src/layouts/quilted.dart';
export 'src/layouts/staired.dart';
export 'src/layouts/woven.dart';
export 'src/rendering/sliver_masonry_grid.dart';
export 'src/rendering/sliver_simple_grid_delegate.dart';
export 'src/widgets/aligned_grid_view.dart';
export 'src/widgets/masonry_grid_view.dart';
export 'src/widgets/sliver_aligned_grid.dart';
export 'src/widgets/sliver_masonry_grid.dart';
export 'src/widgets/staggered_grid.dart';
export 'src/widgets/staggered_grid_tile.dart';
2 changes: 1 addition & 1 deletion lib/src/layouts/sliver_patterned_grid_delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class _SliverPatternGridLayout extends SliverGridLayout {
return lastFilledPatternTrailingScrollOffset - mainAxisSpacing;
}

// We have to get the max scroll offset for the run where the tile with
// We have to get the max scroll offset for the track where the tile with
// index, childCount - 1, is.
// TODO(romain): Can be optimized.
final maxIndex = (childCount - 1) % tileCount;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/layouts/staired.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class SliverStairedGridDelegate
i++;
}
if (crossAxisRatioSum > 1) {
// The last ratio is too high. We remove it from this run.
// The last ratio is too high. We remove it from this track.
i--;
}
final tileBottomSpaceSum = tileBottomSpace * (i - startIndex);
Expand Down
4 changes: 2 additions & 2 deletions lib/src/layouts/woven.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ class SliverWovenGridDelegate extends SliverPatternGridDelegate<WovenGridTile> {
crossAxisSpacing;
final crossAxisStride = crossAxisExtent + crossAxisSpacing;
final patternCount = pattern.length;
// The minimum aspect ratio give us the main axis extent of a run.
// The minimum aspect ratio give us the main axis extent of a track.
final maxMainAxisExtentRatio =
pattern.map((t) => t.crossAxisRatio / t.aspectRatio).reduce(math.max);
final mainAxisExtent = crossAxisExtent * maxMainAxisExtentRatio +
(isHorizontal ? 0 : tileBottomSpace);

// We always provide 2 runs where the layout follow this pattern:
// We always provide 2 tracks where the layout follow this pattern:
// A B A || A B A B || A B C || A B C A
// B A B || B A B A || C B A || B A C B

Expand Down
Loading

0 comments on commit ebd911a

Please sign in to comment.