Skip to content

Instantly share code, notes, and snippets.

@paurakhsharma
Last active September 3, 2021 07:12
Show Gist options
  • Save paurakhsharma/e45d9d94ff68f362683fca6a5d16d3c7 to your computer and use it in GitHub Desktop.
Save paurakhsharma/e45d9d94ff68f362683fca6a5d16d3c7 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
void main() async {
runApp(const DynamicHeader());
}
class DynamicHeader extends StatelessWidget {
const DynamicHeader({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late final ScrollController _controller;
bool _isScrollAreaCollapsed = false;
static const titleHeight = 110.0;
static const expandedColor = Color(0xff5379FF);
static const collapsedColor = Color(0xff51C2FE);
final descText = 'This is another dynamic text text tt tt t end';
static const descTextStyle = TextStyle(
color: Colors.white,
fontSize: 20,
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: _controller,
slivers: [
SliverAppBar(
backgroundColor:
_isScrollAreaCollapsed ? collapsedColor : expandedColor,
pinned: true,
title: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
_isScrollAreaCollapsed ? 'Wrapped' : 'Hello',
style: const TextStyle(
fontSize: 34,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 100,
child: IconButton(
onPressed: () {},
icon: Icon(
_isScrollAreaCollapsed
? Icons.expand_less
: Icons.expand_more,
size: 40,
),
),
)
],
)
],
),
collapsedHeight: 60,
expandedHeight: descTextHeight,
bottom: const HeaderBottom(),
flexibleSpace: FlexibleSpaceBar(
background: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
Container(
height: titleHeight,
),
Text(
descText,
style: descTextStyle,
),
],
),
),
),
),
SliverList(
delegate: SliverChildListDelegate(
List.generate(
20,
(index) => ListTile(
title: Text('Item $index'),
),
),
),
)
],
),
);
}
double get descTextHeight {
const padding = 32;
final textPainter = TextPainter(
text: TextSpan(text: descText, style: descTextStyle),
textScaleFactor: MediaQuery.of(context).textScaleFactor,
maxLines: 1,
textDirection: TextDirection.ltr,
)..layout();
final width = textPainter.size.width;
final height = textPainter.size.height;
final screenWidth = MediaQuery.of(context).size.width;
final numberofLines = (width / (screenWidth - padding)).ceil();
return numberofLines * height + titleHeight + 16;
}
void _scrollListner() {
if (_controller.offset > (descTextHeight - 130)) {
if (_isScrollAreaCollapsed) return;
setState(() {
_isScrollAreaCollapsed = true;
});
} else {
if (!_isScrollAreaCollapsed) return;
setState(() {
_isScrollAreaCollapsed = false;
});
}
}
@override
void initState() {
super.initState();
_controller = ScrollController();
_controller.addListener(_scrollListner);
}
@override
void dispose() {
_controller.removeListener(_scrollListner);
_controller.dispose();
super.dispose();
}
}
class HeaderBottom extends StatelessWidget implements PreferredSizeWidget {
const HeaderBottom({
Key? key,
}) : preferredSize = const Size.fromHeight(50.0),
super(key: key);
@override
final Size preferredSize;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
color: Colors.black.withOpacity(0.2),
height: 50,
child: ListView.separated(
separatorBuilder: (context, index) => const SizedBox(width: 8),
itemCount: 20,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Tab(
child: Text(
'Tab ${index + 1}',
style: TextStyle(
color:
index == 0 ? Colors.white : Colors.white.withOpacity(0.6),
),
),
);
},
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment