Following a tutorial on StaggeredGridView
, I successfully built a page to display staggered grids of text and an icon. The tutorial stopped short on explaining how to link each grid item separately. I am aware of onTap, GestureDetector, OnPressed, but I can not figure out how to implement any of these in this grid layout so that each element can link to a different material page route (or _UrlLauncher, etc.)
child: Material(
child: StaggeredGridView.count(
crossAxisCount: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 16,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0),
children: < Widget > [
MyItems(Icons.shop, "Tecxt Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
MyItems(Icons.shop, "Text Here", 0xff42a5f5),
],
staggeredTiles: [
StaggeredTile.extent(2, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(2, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(2, 150.0),
],
),
), //material
For each "MyItems" we created a Method and parameters:
Material MyItems(IconData icon, String heading, int color) {
return Material(color: Colors.white,
elevation: 12.0,
shadowColor: Color(0xff2962ff),
borderRadius: BorderRadius.circular(20.0),
child: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: < Widget > [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: < Widget > [
//Text here
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(heading,
style: TextStyle(
color: new Color(color),
fontSize: 20.0,
),
),
), //text
//icon
Material(
color: new Color(color),
borderRadius: BorderRadius.circular(24.0),
child: Padding(padding: const EdgeInsets.all(16.0),
child: Icon(
icon,
color: Colors.white,
size: 20.0,
),
),
),
],
),
]))),
);
There doesn't appear to be any information on how to solve this. The only follow up I could find from the author was "There are couple of ways to tackle it":
Use Keys property of the widget
TagButton(onPressed: (k) => onPress(k)), void onPress(Key id) { print('pressed $id'); }
2.Assign a callback that calls a different method for each button
Or you can pass a parameter like shown below and use a switch to identify the parameter value and call the corresponding method.
onPressed: () => onButtonPressed('okButton'),
But after much struggle, I just can't comprehend this. Is it even possible to individually link each staggered grid to their own unique link (page route, UrlLauncher, etc.?
You can copy paste run full code below
You can pass route name as String
code snippet
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => Example01(),
'/first': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
...
List<Widget> _tiles = const <Widget>[
const MyItems(Icons.shop, "Text1 Here", 0xff42a5f5, "/first"),
const _Example01Tile(Colors.green, Icons.widgets),
const _Example01Tile(Colors.amber, Icons.panorama_wide_angle),
const MyItems(Icons.shop, "Text 2 Here", 0xff42a5f5, "/second"),
...
class MyItems extends StatelessWidget {
const MyItems(this.icon, this.heading, this.color, this.routeName);
...
IconButton(
icon: Icon(icon),
iconSize: 20,
color: Colors.white,
onPressed: () {
Navigator.pushNamed(context, routeName);
},
)
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
List<StaggeredTile> _staggeredTiles = const <StaggeredTile>[
StaggeredTile.extent(2, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(2, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(1, 150.0),
StaggeredTile.extent(2, 150.0),
];
List<Widget> _tiles = const <Widget>[
const MyItems(Icons.shop, "Text1 Here", 0xff42a5f5, "/first"),
const _Example01Tile(Colors.green, Icons.widgets),
const _Example01Tile(Colors.amber, Icons.panorama_wide_angle),
const MyItems(Icons.shop, "Text 2 Here", 0xff42a5f5, "/second"),
const _Example01Tile(Colors.deepOrange, Icons.send),
const _Example01Tile(Colors.indigo, Icons.airline_seat_flat),
const _Example01Tile(Colors.red, Icons.bluetooth),
const _Example01Tile(Colors.pink, Icons.battery_alert),
const _Example01Tile(Colors.purple, Icons.desktop_windows),
const _Example01Tile(Colors.blue, Icons.radio),
];
class Example01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Example 01'),
),
body: Padding(
padding: const EdgeInsets.only(top: 12.0),
child: StaggeredGridView.count(
crossAxisCount: 4,
staggeredTiles: _staggeredTiles,
children: _tiles,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
padding: const EdgeInsets.all(4.0),
)));
}
}
class _Example01Tile extends StatelessWidget {
const _Example01Tile(this.backgroundColor, this.iconData);
final Color backgroundColor;
final IconData iconData;
@override
Widget build(BuildContext context) {
return Card(
color: backgroundColor,
child: InkWell(
onTap: () {},
child: Center(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
iconData,
color: Colors.white,
),
),
),
),
);
}
}
class MyItems extends StatelessWidget {
const MyItems(this.icon, this.heading, this.color, this.routeName);
final int color;
final IconData icon;
final String heading;
final String routeName;
@override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
elevation: 12.0,
shadowColor: Color(0xff2962ff),
borderRadius: BorderRadius.circular(20.0),
child: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//Text here
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
heading,
style: TextStyle(
color: new Color(color),
fontSize: 18.0,
),
),
), //text
//icon
Material(
color: new Color(color),
borderRadius: BorderRadius.circular(24.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: IconButton(
icon: Icon(icon),
iconSize: 20,
color: Colors.white,
onPressed: () {
Navigator.pushNamed(context, routeName);
},
),
),
),
],
),
]))),
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => Example01(),
'/first': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("First Screen");
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("Second Screen");
}
}