Jørgen Andersen
Jørgen Andersen

Reputation: 641

How can I make a fadein "decoration image" effect in Flutter

I want to build a widget that displays an image as a background behind some content. I know I can do this with a DecorationImage the problem is that I want the image to fade in as it might not be available right away.

So I want it to look like this after the image has faded in. enter image description here

class DecorationExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          fit: BoxFit.fitWidth,
          image: NetworkImage(
              'https://images.pexels.com/photos/414612/pexels-photo-414612.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'),
        ),
      ),
      child: Column(
        // Center the content dead center.
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          //Expand the column to take up the availble width
          Container(width: double.infinity),
          Text('Can be'),
          Text('any'),
          Text('size'),
          Text('Depending on the number of rows')
        ],
      ),
    );
  }
}

My first instinct is to use a stack. The problem is that I need the stack to constrain itself to the height of the column which may vary depending on the content. enter image description here

import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';

class StackedImageTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          width: double.infinity,
          child: _fadeInImage(),
        ),
        _content(),
      ],
    );
  }

  _content() => Column(
        // Center the content dead center.
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          //Expand the column to take up the availble width
          Container(width: double.infinity),
          Text('Can be'),
          Text('any'),
          Text('height'),
          Text('Depending on the number of rows')
        ],
      );

  _fadeInImage() => FadeInImage.memoryNetwork(
        placeholder: kTransparentImage,
        fit: BoxFit.fitWidth,
        image: 'https://images.pexels.com/photos/414612/pexels-photo-414612.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
      );
}

To run the example include this dependency in your pubspec.yaml file:

transparent_image: ^1.0.0

So basically how can I achieve the same effect as with a decoration image(DecorationExample) but make it so that the image fades nicely into view(like in the StackedImageTest widget)?

Upvotes: 0

Views: 1451

Answers (1)

J&#248;rgen Andersen
J&#248;rgen Andersen

Reputation: 641

Pretty simple as it turns out😅 Wrapping the first layer in the stack with a Positioned.fill() seems to do the trick

class FadeInDecorationContainer extends StatelessWidget {
  final Widget child;
  final String imgUrl;

  const FadeInDecorationContainer({Key key, this.child, this.imgUrl}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Positioned.fill(child: _fadeInImage()),
        child,
      ],
    );
  }

  _fadeInImage() => FadeInImage.memoryNetwork(
        placeholder: kTransparentImage,
        fit: BoxFit.fitWidth,
        image: imgUrl,
      );
}

To run the example include this dependency in your pubspec.yaml file:

transparent_image: ^1.0.0

Upvotes: 1

Related Questions