如何在 Flutter 中编写一个能够获取图像作为输入的卡片小部件?

How do I write in Flutter a card widget with the ability to get images as input?

我只编写了一个能够在上面显示图片和文本的小部件。我想更改小部件,使其成为一个模板,我可以在其中发送所需的文本和图像并显示它,但现在整个应用程序中只有一个相同的图像。我怎样才能将图像作为输入发送到 buildImageCard();

带有小部件的主页:

import 'package:project_alpha/widgets/ImageCard.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      // gridDelegate:
      //     SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      padding: EdgeInsets.all(16),
      children: [
        buildImageCard(),
        buildImageCard(),
        buildImageCard(),
        buildImageCard(),
        buildImageCard(),
        buildImageCard(),
      ],
    );
  }
}

小部件:


Widget buildImageCard() => Card(
      clipBehavior: Clip.antiAlias,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(24),
      ),
      child: Column(
        children: [
          Stack(
            children: [
              Ink.image(
                image: AssetImage('assets/images/screen.png'),
                height: 240,
                fit: BoxFit.cover,
              ),
              Positioned(
                bottom: 30,
                right: 16,
                left: 16,
                child: Text(
                  'Interesting fact!',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                    fontSize: 24,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );

如果您使用 AssetImage,您只需要图像的路径。您可以像任何其他参数一样将该路径作为 String 传递给构建器函数。

Widget buildImageCard(String imagePath) => Card(
      clipBehavior: Clip.antiAlias,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(24),
      ),
      child: Column(
        children: [
          Stack(
            children: [
              Ink.image(
                image: AssetImage(imagePath),
                height: 240,
                fit: BoxFit.cover,
              ),
              Positioned(
                bottom: 30,
                right: 16,
                left: 16,
                child: Text(
                  'Interesting fact!',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                    fontSize: 24,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );




class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      // gridDelegate:
      //     SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      padding: EdgeInsets.all(16),
      children: [
        buildImageCard('assets/images/screen.png'),
        buildImageCard('assets/images/screen2.png'),
        buildImageCard('assets/images/screen3.png'),
        buildImageCard('assets/images/screen4.png'),
        buildImageCard('assets/images/screen5.png'),
        buildImageCard('assets/images/screen6.png'),
      ],
    );
  }
}

我强烈建议您避免创建返回 Widget 的方法,考虑创建一个扩展 Stateless 或 Stateful 的整个 widget,这样效率更高。

为了解决您的问题,这是解决方案之一

import 'package:flutter/material.dart';

class ImageCard extends StatelessWidget {

  final String fact;
  final AssetImage image;

  const ImageCard(this.fact, this.image);

  @override
  Widget build(BuildContext context) {
    return Card(
      clipBehavior: Clip.antiAlias,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(24),
      ),
      child: Column(
        children: [
          Stack(
            children: [
              Ink.image(
                image: image,
                height: 240,
                fit: BoxFit.cover,
              ),
              Positioned(
                bottom: 30,
                right: 16,
                left: 16,
                child: Text(
                  fact,
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                    fontSize: 24,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

您可以通过调用以下方法实例化此小部件

ImageCard("Your fact", AssetImage("assets/images/image.png"))

试试这个,

Widget buildImageCard({String title, String imageAssetName,}) => Card( // CHANGED HERE
  clipBehavior: Clip.antiAlias,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(24),
  ),
  child: Column(
    children: [
      Stack(
        children: [
          Ink.image(
            image: AssetImage('assets/images/$imageAssetName.png'),   // CHANGED HERE
            height: 240,
            fit: BoxFit.cover,
          ),
          Positioned(
            bottom: 30,
            right: 16,
            left: 16,
            child: Text(
              title,                    // CHANGED HERE
              style: TextStyle(
                fontWeight: FontWeight.bold,
                color: Colors.white,
                fontSize: 24,
              ),
            ),
          ),
        ],
      ),
    ],
  ),
);

通过使用此概念的任何其他配置。