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:

res

Share:
121
Pillo
Author by

Pillo

Updated on November 25, 2022

Comments

  • Pillo
    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:

    enter image description here

    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