0

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),
  );
Jack Duffy
  • 193
  • 12

3 Answers3

3

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),
  );
1

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

Robiness
  • 79
  • 3
  • Stack and Align with Alignment.bottomCenter are very clean for this specific case, I came to give this exact same answer. – TheFunk Jan 25 '22 at 21:25
0

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,
                  ),
                ]
              ),
            ),
          )
        ],
      ),
Saddan
  • 1,546
  • 16
  • 19