Sticky Header Flutter Example

In this article, we are going to integrate sticky header view in listview in flutter application. You can also check flutter listview related articles.

In this flutter example, we are displaying football clubs names with associated players names. We show football club name as sticky header in flutter list view. Football players names are displayed below each related club name sticky header row. We will not place listview inside listview to display player names with their clubs. We will add players names as dynamic widget to children property of column inside listview.

 

Add required package in pubspec.yaml file

sticky_headers: ^0.2.0
 
 

Types of Sticky Header

import ‘package:flutter/material.dart’;
import ‘package:flutterstickyheadersample/my_animated_sticky_header_screen.dart’;
import ‘package:flutterstickyheadersample/my_overlapped_sticky_header_screen.dart’;
import ‘package:flutterstickyheadersample/my_simple_sticky_header_screen.dart’;

class MyStickyHeaderScreen extends StatefulWidget {
@override
_MyStickyHeaderScreenState createState() => _MyStickyHeaderScreenState();
}

class _MyStickyHeaderScreenState extends State<MyStickyHeaderScreen> {
HashMap<String, List<String>> mapSoccerPlayers =
HashMap<String, List<String>>();

@override
void initState() {
super.initState();
mapSoccerPlayers[‘Manchester United’] = [
‘Cristiano Ronaldo’,
‘Bruno Fernandes’
];
mapSoccerPlayers[‘Manchester City’] = [‘Kevin De Bruyne’];
mapSoccerPlayers[‘Liverpool’] = [
‘Virgil van Dijk’,
‘Mohamed Salah’,
‘Trent Alexander-Arnold’
];
mapSoccerPlayers[‘Chelsea’] = [‘Romelu Lukaku’, ‘Thiago Silva’];
mapSoccerPlayers[‘Tottenham’] = [‘Harry Kane’, ‘Son Heung-min’];
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Flutter Stickey Header Sample’)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.orangeAccent,
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: 15)),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
MySimpleStickyHeaderScreen(mapSoccerPlayers)));
},
child: Text(‘Simple Sticky Header’,
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold))),
SizedBox(height: 25),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.redAccent,
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: 15)),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
MyAnimatedStickyHeaderScreen(mapSoccerPlayers)));
},
child: Text(‘Animated Sticky Header’,
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold))),
SizedBox(height: 25),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.deepOrangeAccent,
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: 15)),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
MyOverlappedStickyHeaderScreen(mapSoccerPlayers)));
},
child: Text(‘Overlapped Sticky Header’,
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold))),
],
),
));
}
}

 
 
 
 

Simple Sticky Header

import ‘dart:collection’;
import ‘package:flutter/material.dart’;
import ‘package:sticky_headers/sticky_headers.dart’;

class MySimpleStickyHeaderScreen extends StatelessWidget {
HashMap<String, List<String>> mapSoccerPlayers =
HashMap<String, List<String>>();
ScrollController myScrollContainer = ScrollController();

MySimpleStickyHeaderScreen(this.mapSoccerPlayers);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Simple Sticky Header’)),
body: Container(
child: ListView.builder(
primary: myScrollContainer == null,
controller: myScrollContainer,
itemCount: mapSoccerPlayers.keys.length,
itemBuilder: (context, index) {
String getKey = mapSoccerPlayers.keys.toList()[index];
List<String> getValuesFromKey = mapSoccerPlayers[getKey];
List<Widget> listPlayerNamesWidgets = [];
for (var playerName in getValuesFromKey) {
listPlayerNamesWidgets.add(Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Text(
playerName,
style: TextStyle(fontSize: 25),
)));
}
return Material(
child: StickyHeader(
controller: myScrollContainer,
header: Container(
height: 60,
color: Colors.orangeAccent,
padding: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
child: Text(
getKey,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: listPlayerNamesWidgets,
)),
);
},
),
),
);
}
}

 
 
 
sticky header
 
 

Animated Header for List View

import ‘dart:collection’;
import ‘package:flutter/material.dart’;
import ‘package:sticky_headers/sticky_headers.dart’;

class MyAnimatedStickyHeaderScreen extends StatelessWidget {
HashMap<String, List<String>> mapSoccerPlayers =
HashMap<String, List<String>>();
ScrollController myScrollContainer = ScrollController();

MyAnimatedStickyHeaderScreen(this.mapSoccerPlayers);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Animated Sticky Header’)),
body: Container(
child: ListView.builder(
primary: myScrollContainer == null,
controller: myScrollContainer,
itemCount: mapSoccerPlayers.keys.length,
itemBuilder: (context, index) {
String getKey = mapSoccerPlayers.keys.toList()[index];
List<String> getValuesFromKey = mapSoccerPlayers[getKey];
List<Widget> listPlayerNamesWidgets = [];
for (var playerName in getValuesFromKey) {
listPlayerNamesWidgets.add(Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Text(
playerName,
style: TextStyle(fontSize: 25),
)));
}
return Material(
child: StickyHeaderBuilder(
controller: myScrollContainer, // Optional
builder: (BuildContext context, double stuckAmount) {
stuckAmount = 1.0 – stuckAmount.clamp(0.0, 1.0);
return Container(
height: 60,
color: Color.lerp(Colors.orangeAccent,
Colors.pinkAccent, stuckAmount),
padding: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
Expanded(
child: Text(
getKey,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
Offstage(
offstage: stuckAmount <= 0.0,
child: Opacity(
opacity: stuckAmount,
child: IconButton(
icon: Icon(Icons.favorite, color: Colors.white),
onPressed: () => ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(
getKey + ‘ is selected as favorite’,
style: TextStyle(fontWeight: FontWeight.bold),
))),
),
),
),
],
),
);
},
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: listPlayerNamesWidgets,
)),
);
},
),
),
);
}
}

 
 
 
sticky header
 
 

Overlapped Sticky Header in Flutter

import ‘dart:collection’;
import ‘package:flutter/material.dart’;
import ‘package:sticky_headers/sticky_headers.dart’;

class MyOverlappedStickyHeaderScreen extends StatelessWidget {
HashMap<String, List<String>> mapSoccerPlayers =
HashMap<String, List<String>>();
ScrollController myScrollContainer = ScrollController();

MyOverlappedStickyHeaderScreen(this.mapSoccerPlayers);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Overlapped Sticky Header’)),
body: Container(
child: ListView.builder(
primary: myScrollContainer == null,
controller: myScrollContainer,
itemCount: mapSoccerPlayers.keys.length,
itemBuilder: (context, index) {
String getKey = mapSoccerPlayers.keys.toList()[index];
List<String> getValuesFromKey = mapSoccerPlayers[getKey];
List<Widget> listPlayerNamesWidgets = [];
for (var playerName in getValuesFromKey) {
listPlayerNamesWidgets.add(Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Text(
playerName,
style: TextStyle(fontSize: 25),
)));
}
return Material(
child: StickyHeaderBuilder(
overlapHeaders: true,
controller: myScrollContainer, // Optional
builder: (BuildContext context, double stuckAmount) {
stuckAmount = 1.0 – stuckAmount.clamp(0.0, 1.0);
return Container(
height: 60,
color: Colors.deepOrangeAccent.withOpacity(0.6 + stuckAmount * 0.4),
padding: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
child: Text(
getKey,
style: TextStyle(
fontSize: 25,
color: Colors.white),
),
);
},
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: listPlayerNamesWidgets,
)),
);
},
),
),
);
}
}

 
 
sticky header
 

One thought on “Sticky Header Flutter Example

Leave a Reply