Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FadeInImage in BoxDecoration

Tags:

flutter

I love the FadeInImage

I can do this

child: FadeInImage.assetNetwork(
    image: 'https://placeimg.com/640/480/any',
    placeholder: 'assets/images/loading.gif',
  ),

I want to use the FadeInImage in a BoxDecoration as below.

decoration: BoxDecoration(
  borderRadius: BorderRadius.circular(8.0),
  image: DecorationImage(
    image: FadeInImage.assetNetwork(
        '${document['image']}'),
    fit: BoxFit.cover,
  ),
),

I get this error:

The argument type 'FadeInImage' can't be assigned to the parameter type 'ImageProvider'

How would I go about it?

Use Case

In a carousel, put in placeholder, before network loaded image comes in

Here's my carousel Widget (I'm using the carousel_slider package for Flutter)

  Widget _carouselSlider(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('events').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Text('Loading...');
          default:
            return CarouselSlider(
              height: 150.0,
              enlargeCenterPage: true,
              enableInfiniteScroll: false,
              items: snapshot.data.documents.map((DocumentSnapshot document) {
                print('Listing the documents: $document');
                return Builder(
                  builder: (BuildContext context) {
                    return GestureDetector(
                      onTap: () {
                        print('I am clicked');
                        Navigator.pushNamed(context, '/detail');
                      },
                      child: Container(
                        width: MediaQuery.of(context).size.width,
                        margin: EdgeInsets.only(
                            left: 5.0, right: 5.0, bottom: 20.0),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(8.0),
                          image: DecorationImage(
                            image: NetworkImage('${document['image']}'),
                            fit: BoxFit.cover,
                          ),
                        ),
                        child: Center(
                          child: Text(
                            '${document['name']}',
                            style: TextStyle(fontSize: 16.0),
                          ),
                        ),
                      ),
                    );
                  },
                );
              }).toList(),
            );
        }
      },
    );
  }

So, for the part

image: DecorationImage(
                        image: NetworkImage('${document['image']}'),
                        fit: BoxFit.cover,
                      ),

I wish to have a placeholder approach, instead of only the text until network loaded image arrives.

like image 920
KhoPhi Avatar asked May 29 '19 19:05

KhoPhi


3 Answers

Here is the code.

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
          child: FutureBuilder<bool>(
        future: _myFuture(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) return _yourWidget();
          return CircularProgressIndicator();
        },
      )),
    );
  }

  Widget _yourWidget() {
    return Stack(
      children: <Widget>[
        Center(
          child: FadeInImage(
            width: 300,
            height: 300,
            placeholder: AssetImage(chocolateImage),
            image: NetworkImage(poolImageUrl),
            fit: BoxFit.cover,
          ),
        ),
        Center(child: Text('Pool', style: TextStyle(fontSize: 36.0, color: Colors.white, fontWeight: FontWeight.bold))),
      ],
    );
  }

  Future<bool> _myFuture() async {
    await Future.delayed(Duration(milliseconds: 10500));
    return true;
  }
}
like image 64
CopsOnRoad Avatar answered Oct 16 '22 10:10

CopsOnRoad


I achieved something similar. This image is a hero image at the top of the page, hence the height. The combination of width and BoxFit.cover make the image cover the viewport. The loader is (visually) hidden when the image loads.

final imageWithLoader = Container(
    height: MediaQuery.of(context).size.height * 0.5,
    child: Stack(children: <Widget>[
      Center(child: CircularProgressIndicator()),
      Center(
        child: FadeInImage.memoryNetwork(
            placeholder: kTransparentImage,
            image: library.url,
            width: MediaQuery.of(context).size.width,
            fit: BoxFit.cover),
      ),
    ]));
like image 3
Kildareflare Avatar answered Oct 16 '22 09:10

Kildareflare


I believe that you can use the .image method on the image to return a provider.

DecorationImage(
          fit: BoxFit.fitHeight,
          image:
            FadeInImage(
              placeholder:
                  AssetImage('assets/images/global/800x.gif'),
              image: <<some image provider>>,
            ).image,
        ),
like image 3
Craig Avatar answered Oct 16 '22 10:10

Craig