Created
March 30, 2018 12:17
-
-
Save MarcinusX/e389a9df7e1082f98d1c8f9b6f66d0d0 to your computer and use it in GitHub Desktop.
Sliver AppBar case study created for post on www.marcinszalek.pl
This file contains 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'; | |
void main() => runApp(new MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
title: 'Sliver Fab Example', | |
theme: new ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: new MyHomePage(), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
@override | |
MyHomePageState createState() { | |
return new MyHomePageState(); | |
} | |
} | |
class MyHomePageState extends State<MyHomePage> { | |
ScrollController _scrollController; | |
@override | |
void initState() { | |
super.initState(); | |
_scrollController = new ScrollController(); | |
_scrollController.addListener(() => setState(() {})); | |
} | |
@override | |
void dispose() { | |
_scrollController.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return new Scaffold( | |
body: new Stack( | |
children: <Widget>[ | |
new CustomScrollView( | |
controller: _scrollController, | |
slivers: [ | |
new SliverAppBar( | |
expandedHeight: 256.0, | |
pinned: true, | |
flexibleSpace: new FlexibleSpaceBar( | |
title: new Text("SliverFab Example"), | |
background: new Image.asset( | |
"img.jpg", | |
fit: BoxFit.cover, | |
), | |
), | |
), | |
new SliverList( | |
delegate: new SliverChildListDelegate( | |
new List.generate( | |
20, | |
(int index) => new ListTile(title: new Text("Item $index")), | |
), | |
), | |
), | |
], | |
), | |
_buildFab(), | |
], | |
), | |
); | |
} | |
Widget _buildFab() { | |
//starting fab position | |
final double defaultTopMargin = 256.0 - 4.0; | |
//pixels from top where scaling should start | |
final double scaleStart = 96.0; | |
//pixels from top where scaling should end | |
final double scaleEnd = scaleStart / 2; | |
double top = defaultTopMargin; | |
double scale = 1.0; | |
if (_scrollController.hasClients) { | |
double offset = _scrollController.offset; | |
top -= offset; | |
if (offset < defaultTopMargin - scaleStart) { | |
//offset small => don't scale down | |
scale = 1.0; | |
} else if (offset < defaultTopMargin - scaleEnd) { | |
//offset between scaleStart and scaleEnd => scale down | |
scale = (defaultTopMargin - scaleEnd - offset) / scaleEnd; | |
} else { | |
//offset passed scaleEnd => hide fab | |
scale = 0.0; | |
} | |
} | |
return new Positioned( | |
top: top, | |
right: 16.0, | |
child: new Transform( | |
transform: new Matrix4.identity()..scale(scale), | |
alignment: Alignment.center, | |
child: new FloatingActionButton( | |
onPressed: () => {}, | |
child: new Icon(Icons.add), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment