Reputation: 890
Currently I have List of FeaturedBlock. Featured block contains header and list of products. So the problem is that I'm not sure how to add that block(header with gridList) to CustomScrollView. So the structure is:
--------------
|SliverAppBar|
--------------
...some elements
--------------
| Header | ----> Featured Block header
--------------
------ -------
| | | | ----> Featured Block products
| | | |
------ -------
------ -------
| | | |
| | | |
------ -------
--------------
| Header | ----> Featured Block header
--------------
------ -------
| | | | ----> Featured Block products
| | | |
------ -------
------ -------
| | | |
| | | |
------ -------
So, how to convert FeaturedBlock to Sliver element?
Upvotes: 0
Views: 963
Reputation: 54367
You can copy paste run full code below
You can use SliverPersistentHeader
and SliverGrid.count
and change crossAxisCount
per your request
working demo
full code
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Collapsing List Demo')),
body: CollapsingList(),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.minHeight,
@required this.maxHeight,
@required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new SizedBox.expand(child: child);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
class CollapsingList extends StatelessWidget {
SliverPersistentHeader makeHeader(String headerText) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 60.0,
maxHeight: 200.0,
child: Container(
color: Colors.lightBlue, child: Center(child: Text(headerText))),
),
);
}
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('SliverAppBar'),
backgroundColor: Colors.green,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network('https://picsum.photos/250?image=9',
fit: BoxFit.cover),
),
),
makeHeader('Header Section 1'),
SliverGrid.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
],
),
makeHeader('Header Section 2'),
SliverGrid.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
],
),
makeHeader('Header Section 3'),
SliverGrid.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
],
),
makeHeader('Header Section 4'),
SliverGrid.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
],
),
],
);
}
}
working demo 2
full code 2
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
List<Widget> widgetList = [];
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
SliverPersistentHeader makeHeader(String headerText) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 60.0,
maxHeight: 200.0,
child: Container(
color: Colors.lightBlue, child: Center(child: Text(headerText))),
),
);
}
void _add() {
count = count + 1;
widgetList.add(makeHeader(count.toString()));
widgetList.add(
SliverGrid.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
],
),
);
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Collapsing List Demo')),
body: CollapsingList(),
floatingActionButton: FloatingActionButton(
onPressed: _add,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.minHeight,
@required this.maxHeight,
@required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new SizedBox.expand(child: child);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
class CollapsingList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('SliverAppBar'),
backgroundColor: Colors.green,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network('https://picsum.photos/250?image=9',
fit: BoxFit.cover),
),
),
...widgetList
],
);
}
}
Upvotes: 1