Skip to content

Instantly share code, notes, and snippets.

@rydmike
Last active February 17, 2020 02:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rydmike/5997737351268ad08e35e9f406e73f39 to your computer and use it in GitHub Desktop.
Save rydmike/5997737351268ad08e35e9f406e73f39 to your computer and use it in GitHub Desktop.
Flutter Padding Examples of GridView and StaggaredGrid (Not DartPad Compatible example)
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
void main() {
return runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
systemNavigationBarColor: Colors.grey[100], // navigation bar color
statusBarColor: Colors.indigo,
statusBarIconBrightness: Brightness.light,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
return MaterialApp(
title: 'Flutter Advanced Grids',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.indigo,
scaffoldBackgroundColor: Colors.grey[100],
buttonTheme: ButtonThemeData(
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.indigo),
textTheme: ButtonTextTheme.primary,
),
),
home: ExamplesPage(title: 'Flutter GridView Padding Examples'),
);
}
}
class ExamplesPage extends StatelessWidget {
ExamplesPage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
),
body: SingleChildScrollView(
padding: EdgeInsets.only(top: 40),
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(),
),
Container(
width: 410,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('ISSUE - WEB Shadows',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('This page shows some issues with shadows on WEB, they '
'spread out way too much compared to same shadow on a device.'),
RaisedButton(
child: Text('Flutter Web Shadows issue'),
onPressed: () => ShadowsIssuePage.show(context,
title: 'Shadows WEB issue'),
),
SizedBox(height: 20),
Text('EXAMPLE 1 - Simple grid padding case',
style: TextStyle(fontWeight: FontWeight.bold)),
Text(
'Padding on GridView builder is simple, it has a standard '
'padding property, just use it.'),
RaisedButton(
child: Text('Padding on Gridview builder'),
onPressed: () => GridViewBuilderPage.show(context,
title: 'Padding a GridView builder'),
),
SizedBox(height: 20),
Text('EXAMPLE 2 - Padding on SliverGrid',
style: TextStyle(fontWeight: FontWeight.bold)),
Text(
'Padding on SliverGrid is tricker, wrapping entire CustomScrollView '
'with padding FAILS, it will cover shadows!'),
RaisedButton(
child: Text('Padding on Slivers and SliverGrid'),
onPressed: () => SliverGridFailPage.show(context,
title: 'Padding a CustomScrollView and SliverGrid'),
),
SizedBox(height: 20),
Text('EXAMPLE 3 - Padding on SliverGrid with SliverPadding',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Padding on SliverGrid is tricker, use SliverPadding!'),
RaisedButton(
child: Text('Padding on Slivers and SliverGrid'),
onPressed: () => SliverGridPage.show(context,
title: 'Padding a CustomScrollView and SliverGrid'),
),
SizedBox(height: 20),
Text(
'EXAMPLE 4 - SliverPadding works on SliverStaggeredGrid too',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Padding on SliverStaggeredGrid, how? Same way!'),
RaisedButton(
child: Text('Padding on SliverStaggeredGrid'),
onPressed: () => SliverStaggaredGridPage.show(context,
title:
'Padding a CustomScrollView and SliverStaggeredGrid'),
),
SizedBox(height: 20),
Text('EXAMPLE 5 - SliverPadding fancy pants',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Padding on SliverStaggeredGrid works on extend behind '
'AppBar and fancy transparent gradient AppBar too'),
RaisedButton(
child: Text('Padding on SliverStaggeredGrid'),
onPressed: () => SliverStaggaredGridExtPage.show(context,
title:
'Padding a CustomScrollView and SliverStaggeredGrid'),
),
],
),
),
Expanded(
flex: 1,
child: Container(),
),
],
),
),
);
}
}
// *****************************************************************************
class GridItem extends StatelessWidget {
const GridItem({Key key, this.title, this.color, this.height, this.bodyText})
: super(key: key);
final String title;
final Color color;
final double height;
final String bodyText;
@override
Widget build(BuildContext context) {
return Container(
color: color,
padding: const EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
if (height != null && height > 0) SizedBox(height: height),
if (height != null && height > 0)
Text(bodyText,
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold)),
],
),
);
}
}
// *****************************************************************************
class ShadowsIssuePage extends StatelessWidget {
const ShadowsIssuePage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ShadowsIssuePage(title: title)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 30, 20, 50),
child: Column(
children: <Widget>[
Text('Shadows on Web look incorrect',
style: TextStyle(fontSize: 25)),
SizedBox(height: 10),
Text('Shadows bleed too much compared to device rendering',
style: TextStyle(fontSize: 16)),
SizedBox(height: 20),
Card(
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[100],
child: Container(
child: Center(child: Text('Material Card with elevation 0')),
height: 100,
),
),
SizedBox(height: 20),
Card(
elevation: 5,
margin: EdgeInsets.all(0),
color: Colors.indigo[100],
child: Container(
child: Center(child: Text('Material Card with elevation 5')),
height: 100,
),
),
SizedBox(height: 20),
Card(
elevation: 10,
margin: EdgeInsets.all(0),
color: Colors.indigo[100],
child: Container(
child: Center(child: Text('Material Card with elevation 10')),
height: 100,
),
),
SizedBox(height: 20),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.indigo.withOpacity(0.7),
offset: Offset(3, 4),
blurRadius: 6,
spreadRadius: 3,
),
],
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Colors.indigo[100],
),
child: Center(child: Text('Container with custom BoxShadow')),
height: 100,
),
),
SizedBox(height: 20),
SelectableText(
'The fonts on WEB are also fuzzier, like too much antialias'),
SelectableText(
'The shadow issue is reported here: https://github.com/flutter/flutter/issues/32215 '),
],
),
),
),
);
}
}
// *****************************************************************************
class GridViewBuilderPage extends StatelessWidget {
const GridViewBuilderPage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => GridViewBuilderPage(title: title)));
}
@override
Widget build(BuildContext context) {
var _gridItems = List<GridItem>.generate(400, (index) {
return GridItem(
title: 'Tile nr ${index + 1}',
color: Colors.primaries[index % Colors.primaries.length][800]);
});
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
),
body: Scrollbar(
child: GridView.builder(
padding: EdgeInsets.all(15),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 15,
crossAxisSpacing: 15,
childAspectRatio: 2,
),
itemCount: _gridItems.length,
itemBuilder: (context, index) => Card(
elevation: 6,
child: _gridItems[index],
),
),
),
);
}
}
// *****************************************************************************
class SliverGridFailPage extends StatelessWidget {
const SliverGridFailPage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SliverGridFailPage(title: title)));
}
@override
Widget build(BuildContext context) {
var _gridItems = List<GridItem>.generate(400, (index) {
return GridItem(
title: 'Tile nr ${index + 1}',
color: Colors.primaries[index % Colors.primaries.length][800]);
});
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
),
body: Scrollbar(
child: Padding(
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
SizedBox(height: 20),
Text(
'SliverGrid FAILED Padding',
style: Theme.of(context).textTheme.headline4,
),
Text('Texts and header in own SliverList so that we can '
'scroll them with the scrolling grid. If we WRAP the '
'CustomScrollView in Padding, the result is uggly = FAIL! '
'The ELEVATION shadows will be covered by the Padding!'),
SizedBox(height: 20),
]),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 15,
crossAxisSpacing: 15,
childAspectRatio: 2,
),
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return Card(
elevation: 6,
child: _gridItems[index],
);
},
childCount: _gridItems.length,
),
),
],
),
),
),
);
}
}
// *****************************************************************************
class SliverGridPage extends StatelessWidget {
const SliverGridPage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SliverGridPage(title: title)));
}
@override
Widget build(BuildContext context) {
var _gridItems = List<GridItem>.generate(400, (index) {
return GridItem(
title: 'Tile nr ${index + 1}',
color: Colors.primaries[index % Colors.primaries.length][800]);
});
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
),
body: Scrollbar(
child: CustomScrollView(
slivers: <Widget>[
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverList(
delegate: SliverChildListDelegate([
SizedBox(height: 20),
Text(
'SliverGrid OK Padding',
style: Theme.of(context).textTheme.headline4,
),
Text('Texts and header in own SliverList so that we can '
'scroll them with the scrolling grid. To get the '
'Padding effect, we must wrap each Sliver in a '
'SliverPadding!'),
SizedBox(height: 20),
]),
),
),
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 15,
crossAxisSpacing: 15,
childAspectRatio: 2,
),
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return Card(
elevation: 6,
child: _gridItems[index],
);
},
childCount: _gridItems.length,
),
),
)
],
),
),
);
}
}
// *****************************************************************************
class SliverStaggaredGridPage extends StatelessWidget {
const SliverStaggaredGridPage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SliverStaggaredGridPage(title: title)));
}
@override
Widget build(BuildContext context) {
var _gridItems = List<GridItem>.generate(400, (index) {
return GridItem(
title: 'Staggared tile nr ${index + 1}',
color: Colors.primaries[index % Colors.primaries.length][800],
height: 30.0 + Random().nextDouble() * 200,
bodyText:
'Some extra text at the bottom, space above it is random height!');
});
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
),
body: Scrollbar(
child: CustomScrollView(
slivers: <Widget>[
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverList(
delegate: SliverChildListDelegate([
SizedBox(height: 20),
Text(
'SliverStaggaredGrid',
style: Theme.of(context).textTheme.headline4,
),
Text('Texts and header in own SliverList so that we can '
'scroll them with the scrolling grid.'),
SizedBox(height: 20),
]),
),
),
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverStaggeredGrid.countBuilder(
crossAxisCount: 3,
crossAxisSpacing: 15,
mainAxisSpacing: 15,
itemCount: _gridItems.length,
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
itemBuilder: (_, index) {
return Card(
elevation: 6,
child: _gridItems[index],
);
},
),
)
],
),
),
);
}
}
// *****************************************************************************
class SliverStaggaredGridExtPage extends StatelessWidget {
const SliverStaggaredGridExtPage({Key key, this.title}) : super(key: key);
final String title;
static Future<void> show(BuildContext context, {String title}) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SliverStaggaredGridExtPage(title: title)));
}
@override
Widget build(BuildContext context) {
var _gridItems = List<GridItem>.generate(400, (index) {
return GridItem(
title: 'Staggared tile nr ${index + 1}',
color: Colors.primaries[index % Colors.primaries.length][800],
height: 30.0 + Random().nextDouble() * 200,
bodyText:
'Some extra text at the bottom, space above it is random height!');
});
return Scaffold(
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
backgroundColor: Colors.transparent,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.topRight,
colors: [
Colors.indigo,
Colors.indigo.withOpacity(0.6),
],
),
),
child: null,
),
),
body: Scrollbar(
child: CustomScrollView(
slivers: <Widget>[
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverList(
delegate: SliverChildListDelegate([
SizedBox(height: 20 + kToolbarHeight),
Text(
'SliverStaggaredGrid',
style: Theme.of(context).textTheme.headline4,
),
Text('Texts and header in own SliverList so that we can '
'scroll them with the scrolling grid. Here with scroll '
'behind a fancy gradient transparent AppBar!'),
SizedBox(height: 20),
]),
),
),
SliverPadding(
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
sliver: SliverStaggeredGrid.countBuilder(
crossAxisCount: 3,
crossAxisSpacing: 15,
mainAxisSpacing: 15,
itemCount: _gridItems.length,
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
itemBuilder: (_, index) {
return Card(
elevation: 6,
child: _gridItems[index],
);
},
),
)
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment