Flutter: Flutter: How to make finest this Slivers efect
121
You can use Flex
and Flexible
in the _SliverAppBarDelegate
:
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final appBarSize = maxHeight - shrinkOffset;
final proportion = 2 - (maxHeight / appBarSize);
final photoToButton = 160 * proportion;
final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion;
return Flex(
direction: Axis.vertical,
children: <Widget>[
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 8,
child: CircleAvatar(
minRadius: 20.0,
maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0,
backgroundImage: NetworkImage(
'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'),
),
),
Flexible(
flex: 2,
child: Opacity(
opacity: percent,
child: FlatButton(
onPressed: () {},
child: Text(
'Add Photo',
style: TextStyle(
color: Colors.blue, fontSize: 14.0 * proportion),
),
),
),
),
const Divider(
height: 1,
thickness: 0.5,
),
],
),
),
],
);
}
Result:
Author by
Pillo
Updated on November 25, 2022Comments
-
Pillo over 1 year
first sorry for my bad English, I will try to explain myself as best as possible
I made an item from a list with an effect like this:
When I scroll to fill the lower fields, the image size will be reduced to a minimum height, the flat button font size and the flat button opacity too.
The question is: How can I make the effect smoother and the button always stays at the same distance from the image?
This is the code:
SliverPersistentHeader makeHeader(bool pinned) { return SliverPersistentHeader( pinned: pinned, floating: true, delegate: _SliverAppBarDelegate( minHeight: 60.0, maxHeight: 200.0, ), ); }
The _SliverAppBarDelegate:
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate { final double minHeight; final double maxHeight; final bool hideButtonWhenExpanded; _SliverAppBarDelegate( {@required this.minHeight, @required this.maxHeight, this.hideButtonWhenExpanded = true}); @override double get minExtent => minHeight; @override double get maxExtent => math.max(maxHeight, minHeight); @override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { final appBarSize = maxHeight - shrinkOffset; final proportion = 2 - (maxHeight / appBarSize); final photoToButton = 160 * proportion; final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion; return new SizedBox.expand( child: Container( color: Colors.white, child: Stack( alignment: Alignment.topCenter, children: <Widget>[ Positioned( top: 10.0, child: CircleAvatar( minRadius: 20.0, maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0, backgroundImage: NetworkImage( 'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'), ), ), Positioned( left: 0.0, right: 0.0, top: photoToButton, child: Opacity( opacity: percent, child: FlatButton( onPressed: () {}, child: Text( 'Add Photo', style: TextStyle( color: Colors.blue, fontSize: 14.0 * proportion), ), ), ), ), Positioned( left: 0.0, right: 0.0, top: appBarSize - 1.0 > 59.0 ? appBarSize - 1 : 59.0, child: const Divider( height: 1, thickness: 0.5, ), ) ], ), ), ); } @override bool shouldRebuild(_SliverAppBarDelegate oldDelegate) { return maxHeight != oldDelegate.maxHeight || minHeight != oldDelegate .minHeight ; } }
I will thank all possible help