New developer here, need some expertise. I am attempting to create a custom staggered grid view that also allows each tile to be tappable and goes to different pages.
I have tried using inkwell but I cant seem to do that for each individual tile. That then leads to Gesture detector. I can wrap the entire grid view to be tappable with gesture detector, however that makes the entire grid tap-able and all goes to one single page.
Any idea how I can make each individual tile tappable to then link it to another page? When ever I try to do it for each, it completely breaks the layout. Makes each tile the same size. I then tried making each tile size customizable but that didnt work. I attempted to use chatGPT to make it all customizable but it cant quite get there. Ignore the top image asset.
Any and all help is appreciated. Even if I need to use something else to build what il looking to do. See example image of its current state.
actual state of app now, screenshot of phone
using visual studio on windows
dependencies: flutter: sdk: flutter
cupertino_icons: ^1.0.2 google_fonts: ^5.1.0 flutter_staggered_grid_view: ^0.7.0
I have tried using chat GPT to ask it do make each tile tappable, keep the original tile size, each tile points to a different page but I keep going down a web and ever longer code base and it eventually cant gat to what I need it to do.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
google_fonts: ^5.1.0
flutter_staggered_grid_view: ^0.7.0
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:google_fonts/google_fonts.dart';
class FantasyHome extends StatelessWidget {
const FantasyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('new app'),
centerTitle: true,
),
body: Column(
children: [
Image.asset(
'assets/images/bannerbig.png',
fit: BoxFit.cover,
width: double.infinity,
),
Expanded(
child: SingleChildScrollView(
child: GestureDetector(
// Wraped the StaggeredGrid with GestureDetector
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PointsPage(),
),
);
},
child: StaggeredGrid.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
children: const [
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 2,
child: Tile(
index: 0,
color: Color.fromARGB(255, 255, 255, 255),
customText: '50\npoints',
fontSize: 30,
),
),
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 1,
child: Tile(
index: 1,
color: Color.fromARGB(255, 129, 173, 180),
customText: 'Leagues',
),
),
StaggeredGridTile.count(
crossAxisCellCount: 1,
mainAxisCellCount: 1,
child: Tile(
index: 2,
color: Colors.green,
customText: 'Stats',
),
),
StaggeredGridTile.count(
crossAxisCellCount: 1,
mainAxisCellCount: 1,
child: Tile(
index: 3,
color: Colors.red,
customText: 'Custom Text for Tile 3',
),
),
StaggeredGridTile.count(
crossAxisCellCount: 4,
mainAxisCellCount: 2,
child: Tile(
index: 4,
color: Colors.purple,
customText: 'Custom Text for Tile 4',
),
),
],
),
),
),
),
],
),
);
}
}
class Tile extends StatelessWidget {
final int index;
final Color color;
final double fontSize;
final String? customText;
const Tile({
required this.index,
required this.color,
this.fontSize = 15, // Provide a default value for fontSize.
this.customText,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
color: color,
child: Center(
child: Text(
customText ?? 'Tile $index',
style: GoogleFonts.openSans(
fontSize: fontSize,
color: const Color.fromARGB(255, 0, 0, 0),
),
),
),
);
}
}
// Placeholder page for demonstration purposes.
class PointsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Points Page')),
body: Center(child: Text('Points Page Content')),
);
}
}
from the comment I tried this:
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:google_fonts/google_fonts.dart';
class FantasyHome extends StatelessWidget {
const FantasyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('new app'),
centerTitle: true,
),
body: Column(
children: [
Image.asset(
'assets/images/bannerbig.png',
fit: BoxFit.cover,
width: double.infinity,
),
Expanded(
child: SingleChildScrollView(
child: GestureDetector(
// Wrap the StaggeredGrid with GestureDetector
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PointsPage(),
),
);
},
child: StaggeredGridView.countBuilder(
crossAxisCount: 4,
itemCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
staggeredTileBuilder: (index) => StaggeredTile.fit(2),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
switch (index) {
case 0:
Navigator.pushNamed(context, '/tile1');
break;
case 1:
Navigator.pushNamed(context, '/tile2');
break;
case 2:
Navigator.pushNamed(context, '/tile3');
break;
case 3:
Navigator.pushNamed(context, '/tile4');
break;
}
},
child: Tile(
index: index,
color: index == 0
? Color.fromARGB(255, 255, 255, 255)
: index == 1
? Color.fromARGB(255, 129, 173, 180)
: index == 2
? Colors.green
: Colors.red,
customText: index == 0 ? '50\npoints' : 'Custom Text for Tile $index',
fontSize: index == 0 ? 30 : 15,
),
);
},
),
),
),
),
],
),
);
}
}
class Tile extends StatelessWidget {
final int index;
final Color color;
final double fontSize;
final String? customText;
const Tile({
required this.index,
required this.color,
this.fontSize = 15, // Provide a default value for fontSize.
this.customText,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
color: color,
child: Center(
child: Text(
customText ?? 'Tile $index',
style: GoogleFonts.openSans(
fontSize: fontSize,
color: const Color.fromARGB(255, 0, 0, 0),
),
),
),
);
}
}
// Placeholder page for demonstration purposes.
class PointsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Points Page')),
body: Center(child: Text('Points Page Content')),
);
}
}
void main() {
runApp(MaterialApp(
home: FantasyHome(),
routes: {
// Define routes for individual pages
'/tile1': (context) => TilePage(tile: tiles[0]),
'/tile2': (context) => TilePage(tile: tiles[1]),
'/tile3': (context) => TilePage(tile: tiles[2]),
'/tile4': (context) => TilePage(tile: tiles[3]),
},
));
}
// Sample data for the tiles
final List<TileModel> tiles = [
TileModel(title: 'Tile 1', description: 'Description for Tile 1'),
TileModel(title: 'Tile 2', description: 'Description for Tile 2'),
TileModel(title: 'Tile 3', description: 'Description for Tile 3'),
TileModel(title: 'Tile 4', description: 'Description for Tile 4'),
];
class TileModel {
final String title;
final String description;
TileModel({required this.title, required this.description});
}
class TilePage extends StatelessWidget {
final TileModel tile;
TilePage({required this.tile});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(tile.title)),
body: Center(
child: Text(tile.description),
),
);
}
}