I'm trying to achieve this functionality on flutter but honestly have no idea how to do it. I've been trying to figure it out for weeks, I tried flutter_staggered_grid_view, which was kind of the closest to this, but that didn't help either. Does anyone have any idea on how to achieve this effect?
Flutter expandable tiles inside grid view
6.6k views Asked by Chandraaditya At
3
There are 3 answers
0
On
You can use Wrap widget to achieve the result. Please see the code below.
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text("Demo")),
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final int _cells = 8;
final double _containerSizeSmall = 75;
final double _containerSizeLarge = 170;
final double _padding = 10;
int _clicked = 0;
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return SingleChildScrollView(
child: Container(
height: size.height,
width: 240,
child: Wrap(
children: List.generate(
_cells,
(col) => Padding(
padding: EdgeInsets.all(_padding),
child: GestureDetector(
onTap: () {
setState(() {
_clicked != col + 1 ? _clicked = col + 1 : _clicked = 0;
});
},
child: Container(
height: _clicked == col + 1
? _containerSizeLarge
: _containerSizeSmall,
width: _clicked == col + 1
? _containerSizeLarge
: _containerSizeSmall,
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: const BorderRadius.all(
const Radius.circular(5),
),
),
child: Center(child: Text('${col + 1}')),
),
),
),
),
),
),
);
}
}
0
On
You could have a list of the items that should be expanded and lay them out in the grid view accordingly (using flutter_staggered_grid_view for example).
I edited the example written in the library docs to achieve the following result:
Basically,
create a
StatefulWidget
and add a list to it (_expandedIndices
). The purpose of the list is to keep track of the indices of the items that are expanded.add a
GestureDetector
on the grid cells to detect taps and add/remove indices from the list (add the index to the list if it is not already there, otherwise remove it).
Don't forget to put the code that updates the list inside a
setState
.
- in the
staggeredTileBuilder
configurecrossAxisCellCount
andmainAxisCellCount
based on whether the item inindex
should be expanded or not.
class StaggeredGridViewWithExpandableCells extends StatefulWidget {
@override
_StaggeredGridViewWithExpandableCellsState createState() =>
_StaggeredGridViewWithExpandableCellsState();
}
class _StaggeredGridViewWithExpandableCellsState
extends State<StaggeredGridViewWithExpandableCells> {
final _expandedIndices = Set<int>();
@override
Widget build(BuildContext context) {
return StaggeredGridView.countBuilder(
crossAxisCount: 4,
itemCount: 16,
itemBuilder: (BuildContext context, int index) => GestureDetector(
onTap: () => setState(() => _expandedIndices.contains(index) ? _expandedIndices.remove(index) : _expandedIndices.add(index)),
child: new Container(
color: Colors.green,
child: new Center(
child: new CircleAvatar(
backgroundColor: Colors.white,
child: new Text('$index'),
),
)),
),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(_expandedIndices.contains(index) ? 4 : 2, 1),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
);
}
}
You can use the Wrap widget as grid, and use some custom widget with AnimatedContainer to expand and retract the bloc.