Last active
April 9, 2024 10:51
-
-
Save immadisairaj/4c1dda865117fa2276edc1375d807e22 to your computer and use it in GitHub Desktop.
SliverAppBar extend only on Top (zero offset)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
const Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: darkBlue, | |
), | |
debugShowCheckedModeBanner: false, | |
home: const Scaffold( | |
body: Center( | |
child: MyStatefulWidget(), | |
), | |
), | |
); | |
} | |
} | |
class MyStatefulWidget extends StatefulWidget { | |
const MyStatefulWidget({Key? key}) : super(key: key); | |
@override | |
State<MyStatefulWidget> createState() => _MyStatefulWidgetState(); | |
} | |
class _MyStatefulWidgetState extends State<MyStatefulWidget> { | |
late ScrollController _scrollController; | |
// variable height passed to SliverAppBar expanded height | |
late double? _expandedHeight; | |
// constant more height that is given to the expandedHeight | |
// of the SliverAppBar | |
final double _moreHeight = 200; | |
@override | |
initState() { | |
super.initState(); | |
// initialize and add scroll listener | |
_scrollController = ScrollController(); | |
_scrollController.addListener(_scrollListen); | |
// initially expanded height is full | |
_expandedHeight = _moreHeight; | |
} | |
@override | |
dispose() { | |
// dispose the scroll listener and controller | |
_scrollController.removeListener(_scrollListen); | |
_scrollController.dispose(); | |
super.dispose(); | |
} | |
_scrollListen() { | |
final offset = _scrollController.offset; | |
if(offset > _moreHeight) { | |
// if offset is more height, disable expanded height | |
setState(() { | |
_expandedHeight = null; | |
}); | |
} else { | |
// if offset is less, keep increasing the height to offset 0 | |
setState(() { | |
_expandedHeight = _moreHeight - offset; | |
}); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: CustomScrollView( | |
controller: _scrollController, | |
slivers: <Widget>[ | |
SliverAppBar( | |
pinned: false, | |
floating: true, | |
expandedHeight: _expandedHeight, | |
actions: [ | |
TextButton( | |
onPressed: () {}, | |
child: const Text('test'), | |
), | |
], | |
flexibleSpace: FlexibleSpaceBar( | |
// animate the opacity offset when expanded height is changed | |
background: AnimatedOpacity( | |
opacity: _expandedHeight != null ? _expandedHeight! / _moreHeight : 0, | |
duration: const Duration(milliseconds: 300), | |
child: const FlutterLogo(), | |
), | |
), | |
), | |
SliverToBoxAdapter( | |
child: SizedBox( | |
height: 2000, | |
child: Center( | |
child: Container( | |
color: Colors.blue, | |
), | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
DartPad for this => link