Skip to content

Instantly share code, notes, and snippets.

@rydmike

rydmike/main.dart

Last active Dec 19, 2020
Embed
What would you like to do?
EXAMPLE: Padding Slivers with SliverPadding and demo of why Padding does not work
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
return runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
systemNavigationBarColor: Colors.grey[100],
statusBarColor: Colors.indigo,
statusBarIconBrightness: Brightness.light,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
return MaterialApp(
title: 'Flutter 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>[
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 Slivers and SliverGrid'),
onPressed: () => SliverGridFailPage.show(context,
title: 'Padding a CustomScrollView and SliverGrid'),
),
SizedBox(height: 20),
Text('EXAMPLE 3 - Padding SliverGrid with SliverPadding',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Padding on SliverGrid is tricker, use SliverPadding!'),
RaisedButton(
child: Text('Padding Slivers and SliverGrid'),
onPressed: () => SliverGridPage.show(context,
title: 'Padding a CustomScrollView and SliverGrid'),
),
SizedBox(height: 20),
Text('EXAMPLE 4 - SliverGrid fancy pants',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('Padding a SliverGrid works on extend behind '
'AppBar and fancy transparent gradient AppBar too'),
RaisedButton(
child: Text('Padding fancy Slivers and SliverGrid'),
onPressed: () => SliverGridExtPage.show(context,
title: 'Padding a CustomScrollView and SliverGrid'),
),
],
),
),
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 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: 12,
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 a 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 SliverGridExtPage extends StatelessWidget {
const SliverGridExtPage({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) => SliverGridExtPage(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(
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(
'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. Here with scroll '
'behind a fancy gradient transparent AppBar!'),
Text('SliverPadding also works with package '
'StaggaredGrid and its SliverStaggaredGrid but that cannot be '
'shown in DartPad, but here is an another example using it: '),
SelectableText(
'https://gist.github.com/rydmike/5997737351268ad08e35e9f406e73f39'),
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,
),
),
)
],
),
),
);
}
}
@rydmike

This comment has been minimized.

Copy link
Owner Author

@rydmike rydmike commented Feb 21, 2020

You can run this exmple on DartPad here

@searchy2

This comment has been minimized.

Copy link

@searchy2 searchy2 commented Dec 17, 2020

Nice, I'm seeing you everywhere now 👍

@rydmike

This comment has been minimized.

Copy link
Owner Author

@rydmike rydmike commented Dec 17, 2020

Thx and lol, because how on earth did you even find this old thing! 😃
Although this one contains some nice pointers, I should perhaps add it somewhere on my GitHub Pages site https://rydmike.com/gridview to make this and few other ones like it easier find...

@rydmike

This comment has been minimized.

Copy link
Owner Author

@rydmike rydmike commented Dec 19, 2020

19.12.2020 Updated: Removed the web shadows issues, since it is no longer an issue, at least not to the extent it was when I wrote this demo. It was thus a bit confusing to have in here. Also increased the elevation of the demo card to show the difference better now that the elevation is not as exaggerated as it was before we need to use a bit more elevation to show the difference.

@searchy2

This comment has been minimized.

Copy link

@searchy2 searchy2 commented Dec 19, 2020

Right, the web shadows were a big issue. Thank you for helping improve the web fidelity with your demos and issues. Creating reproducible samples takes quite a bit of time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment