Generally when a sliver header is pinned, it's pinned to the top/left, but I need just the header to be pinned to the middle until the next header arrives and bumps it off.
header pinned to left vs desired header pinned at middle
using https://pub.dev/packages/flutter_sticky_header/
import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: CustomScrollView(
scrollDirection: Axis.horizontal,
slivers: [
_StickyHeaderGrid(index: 0),
_StickyHeaderGrid(index: 1),
_StickyHeaderGrid(index: 2),
_StickyHeaderGrid(index: 3),
],
),
),
);
}
}
class _StickyHeaderGrid extends StatelessWidget {
const _StickyHeaderGrid({
Key? key,
this.index,
}) : super(key: key);
final int? index;
@override
Widget build(BuildContext context) {
return SliverStickyHeader(
overlapsContent: true,
header: _SideHeader(index: index),
sliver: SliverPadding(
padding: const EdgeInsets.only(top: 44),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisSpacing: 4.0, mainAxisSpacing: 4.0),
delegate: SliverChildBuilderDelegate(
(context, i) => GridTile(
child: Card(
child: Container(
color: Colors.green,
),
),
footer: Container(
color: Colors.white.withOpacity(0.5),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Grid tile #$i',
style: const TextStyle(color: Colors.black),
),
),
),
),
childCount: 9,
),
),
),
);
}
}
class _SideHeader extends StatelessWidget {
const _SideHeader({
Key? key,
this.index,
}) : super(key: key);
final int? index;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left:0),
child: Align(
alignment: Alignment.topRight,
child: SizedBox(
height: 44.0,
//width: 44.0,
child: Container(
color: Colors.grey,
child: Text('Header $index',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
),
),
),
);
}
}
I've tried adding playing with the padding of the header, as well as adding empty boxes around it but it does not give the right effect (pinned header should be pinned to the middle until the next header arrives to bump it out at which point the previous header should keep moving off the screen).