Flutter 如何在图像上创建横幅

Flutter how to create a banner across an image

Flutter 的新手并试图重新创建一个网站,但无法弄清楚如何在我的名片上显示文本并在文本后面包含全宽不透明度。我还尝试给卡片添加圆角,但我注意到仍然有白色的尖角。任何建议将不胜感激!

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

您收到白角的原因是因为 Card 元素和 Container 的半径不同,您可以通过将 RoundedRectangleBorder 的形状设置为您喜欢的半径来解决此问题。

关于文本背景,如果将文本包裹在一个全宽的Container中,并将背景设置为Container而不是Text,就可以得到你想要的效果。

举个例子:

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

如果您注意到您的图像,您会看到图像上方有一个文本。在这种情况下,我们在 flutter.The 的第一项中使用 Stack 小部件 Stack 将位于底部,下一个项目将位于其上方。我们使用 Position 将第二项位置设置在第一项之上。在这里,我 post 一个具有您预期的输出格式的代码

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,
                  ),
                ]
              ),
            ),
          )
        ],
      ),

边框半径的关键是在 Card 的内容中使用与卡片相同边框半径的 ClipRRect

要将徽章放置在图像上,请使用 StackAlign

可重复使用的小部件可能是这样的:

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,
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

结果看起来this