Jack Duffy
Jack Duffy

Reputation: 351

Flutter how to create a banner across an image

New to flutter and trying to recreate a website but cant figure out how to have text over my card and include the full width opacity behind the text. I also tried to add rounded corners to the card but I'm noticing that there are still white sharp corners. any advice would be greatly appreciated!.

This is what Im aiming for

This is what I currently have

  Card(
    elevation: 5,
    child: Container(
      height: 300,
      width: double.infinity,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(15.0),
          image: DecorationImage(
            fit: BoxFit.cover,
            image: AssetImage(urlImage),
            colorFilter: ColorFilter.mode(
                Colors.black.withOpacity(0.1), BlendMode.softLight),
          )),
      child: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Expanded(
          child: Align(
            alignment: Alignment.bottomCenter,
            child: Text(
              title,
              textAlign: TextAlign.center,
              style: TextStyle(
                color: Colors.white,
                fontSize: 24,
                backgroundColor: Colors.black.withOpacity(0.6),
              ),
            ),
          ),
        ),
      ),
    ),
    margin: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0),
  );

Upvotes: 0

Views: 3414

Answers (3)

Robiness
Robiness

Reputation: 79

The key for the border radius is to use a ClipRRect in the content of the Card with the same border radius as the card.

To position the badge over the image use a Stack with a Align

A reusable widget could be this:

class MenuItem extends StatelessWidget {
  const MenuItem({
    Key? key,
    required this.imageUrl,
    required this.label,
  }) : super(key: key);

  final String imageUrl;
  final String label;

  static const double cornerRadius = 100;

  @override
  Widget build(BuildContext context) {
    return Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(cornerRadius),
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(cornerRadius),
        child: Stack(
          fit: StackFit.expand,
          children: [
            Image.network(
              imageUrl,
              fit: BoxFit.cover,
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                color: Colors.black.withOpacity(0.4),
                height: 100,
                child: Center(
                  child: Text(
                    label,
                    style: const TextStyle(
                      fontSize: 26,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

The result looks this

Upvotes: 1

Saddan
Saddan

Reputation: 1655

If you notice your image you can see above your image there is a text .In this type of case we use Stack widget in flutter.The first item of the Stack will be at the bottom and the next item will be above it. We use Position to set the second item position above the first item. Here I post a code with your expected out put format

Stack(
        children: <Widget>[
          ClipRRect(
            borderRadius: const BorderRadius.only(
              topLeft: Radius.circular(15),
              topRight: Radius.circular(15),
            ),
            child: Image.network(
              'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
              height: 250,
              width: double.infinity,
              fit: BoxFit.cover,
            ),
          ),
          Positioned(
            bottom:0,
            left: 0,
            right: 0,
            child: Container(
              color: Colors.black54,
              padding: const EdgeInsets.symmetric(
                vertical: 5,
                horizontal: 20,
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children:const [ Text(
                    'Spahegeti',
                    style: TextStyle(
                      fontSize: 26,
                      color: Colors.white,
                    ),
                    softWrap: true,
                    overflow: TextOverflow.fade,
                  ),
                ]
              ),
            ),
          )
        ],
      ),

Upvotes: 0

Hampus H&#228;rling
Hampus H&#228;rling

Reputation: 86

The reason you are receiving the white corners is because you have different radius on the Card element and the Container, you can fix this by setting a shape of RoundedRectangleBorder with your preferred radius.

Regarding the text background, you can get what you want if you wrap the Text inide a full width Container and set the background to the Container instead of the Text.

Here's a example:

  Card(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(15.0),
    ),
    elevation: 5,
    child: Container(
      height: 300,
      width: double.infinity,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(15.0),
          image: DecorationImage(
            fit: BoxFit.cover,
            image: AssetImage(urlImage),
            colorFilter: ColorFilter.mode(
                Colors.black.withOpacity(0.1), BlendMode.softLight),
          )),
      child: Align(
        alignment: Alignment.bottomCenter,
        child: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(15.0),
              bottomRight: Radius.circular(15.0)),
            color: Colors.black.withOpacity(0.6),
          ),
          width: double.infinity,
          padding: EdgeInsets.all(10.0),
          child: Text(
            text,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.white,
              fontSize: 24,
            ),
          ),
        ),
      ),
    ),
    margin: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0),
  );

Upvotes: 3

Related Questions