Last active
March 23, 2023 20:22
-
-
Save jonathan-beebe/babf21575290653e499c2dd777f1f7f3 to your computer and use it in GitHub Desktop.
Flutter Responsive Grid Layout
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 characters
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Grid of Cards', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: GridOfCardsPage(), | |
); | |
} | |
} | |
enum WindowSize { compact, medium, expanded } | |
WindowSize getWindowSize(double screenWidth) { | |
if (screenWidth < 600) { | |
return WindowSize.compact; | |
} else if (screenWidth < 1024) { | |
return WindowSize.medium; | |
} else { | |
return WindowSize.expanded; | |
} | |
} | |
int getCrossAxisCount(WindowSize windowSize) { | |
int crossAxisCount; | |
switch (windowSize) { | |
case WindowSize.compact: | |
crossAxisCount = 1; | |
break; | |
case WindowSize.medium: | |
crossAxisCount = 2; | |
break; | |
case WindowSize.expanded: | |
crossAxisCount = 3; | |
break; | |
} | |
return crossAxisCount; | |
} | |
class CardItem extends StatelessWidget { | |
final int index; | |
CardItem({required this.index}); | |
@override | |
Widget build(BuildContext context) { | |
return Card( | |
child: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Text( | |
'Card Title $index', | |
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), | |
), | |
SizedBox(height: 8), | |
Text('Card description $index'), | |
], | |
), | |
), | |
); | |
} | |
} | |
class GridOfCardsPage extends StatelessWidget { | |
void _showModal(BuildContext context, int index) { | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
return Dialog( | |
child: Container( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Text( | |
'Card Title $index', | |
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), | |
), | |
SizedBox(height: 8), | |
Text('Card description $index'), | |
], | |
), | |
), | |
); | |
}, | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Grid of Cards'), | |
), | |
body: Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: LayoutBuilder( | |
builder: (BuildContext context, BoxConstraints constraints) { | |
double screenWidth = MediaQuery.of(context).size.width; | |
WindowSize windowSize = getWindowSize(screenWidth); | |
int crossAxisCount = getCrossAxisCount(windowSize); | |
return GridView.builder( | |
itemCount: 20, | |
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |
crossAxisCount: crossAxisCount, | |
mainAxisSpacing: 8.0, | |
crossAxisSpacing: 8.0, | |
childAspectRatio: 0.75, | |
), | |
itemBuilder: (BuildContext context, int index) { | |
return InkWell( | |
onTap: () => _showModal(context, index), | |
child: CardItem(index: index), | |
); | |
}, | |
); | |
}, | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment