Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Darken edges of an Image in flutter?

How can I add Shades to the edges of an Image in flutter, so that white overlayed text would be readable? I want it to look just like in the Contacts app: Shaded edges

I've already checked the Image class, but all I see there is color and colorBlendMode, which wouldn't be the easiest way of doing this, im sure.

like image 647
Ian Rehwinkel Avatar asked May 26 '18 12:05

Ian Rehwinkel


2 Answers

I solved my issue using following code. (When doing this, dont use box-shadow. It leads to everything being dark):

Stack(
  children: <Widget>[
    Image(
      fit: BoxFit.cover,
      image: AssetImage("assets/test.jpg"),
      height: MediaQuery.of(context).size.width * 0.8,
      width: MediaQuery.of(context).size.width,
    ),
    Container(
      height: MediaQuery.of(context).size.width * 0.8,
      width: MediaQuery.of(context).size.width,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            const Color(0xCC000000),
            const Color(0x00000000),
            const Color(0x00000000),
            const Color(0xCC000000),
          ],
        ),
      ),
    ),
    new Padding(
      padding: const EdgeInsets.all(16.0),
      child: Text("TXT", style: Theme.of(context).primaryTextTheme.title,),
    ),
  ],
),
like image 118
Ian Rehwinkel Avatar answered Oct 01 '22 06:10

Ian Rehwinkel


The accepted answer is working fine for me. But in my case the image is loaded via network so the dark edge is visible even when image is not shown yet, which is wrong to me. So I have another approach by using frameBuilder - which is one of Image's property itself. Another plus for this method is we don't need to use Stack:

Image.network(
        "https://foo.com/bar.jpg",
        width: double.infinity,
        height: expandedHeight,
        fit: BoxFit.fitWidth,
        frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
          if (wasSynchronouslyLoaded || frame != null) {
            return Container(
              child:child,
              foregroundDecoration: BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      colors: [
                        const Color(0xCC000000),
                        const Color(0x00000000),
                        const Color(0x00000000),
                        const Color(0xCC000000),                ]
                  )
              ),
              height: expandedHeight,
              width: double.infinity,
            );
          } else {
            return Container(
              child: CircularProgressIndicator(
                  value: null,
                  backgroundColor: Colors.white),
              alignment: Alignment(0, 0),
              constraints: BoxConstraints.expand(),
            );
          }
        },
      ),

By using this snippet of code I was able to delay the displaying of the dark edge until image is shown. If wasSynchronouslyLoaded is true then that mean the image can be loaded instantly, if it is false then we have to rely on frame to tell if image is available for display or not. If image is not available yet then it will display a CircularProgressIndicator as a place holder for image.

like image 29
The Vinh Luong Avatar answered Oct 01 '22 07:10

The Vinh Luong