Flutter---通用子项的图片个数不同(2)

效果图

说明:版本1的中心水果图片只是简单的排列,这个版本是让图片进行两两交叠

实现步骤

1.构建网格子项

Dart 复制代码
  Widget _buildInAudioItem({
    required String name,
    required List<String> images, //用列表接收图片
    required VoidCallback onTap,
    double imageSize = 40,
  }) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        GestureDetector(
          onTap: onTap,
          child: Container(
            height: 150,
            width: 155,
            decoration: BoxDecoration(
              color: Color(0xFF1B1D2E),
              borderRadius: BorderRadius.circular(10),
            ),
            child: Center(
              child: _buildImageLayout(images, imageSize: imageSize), //传递图片和图片尺寸
            ),
          ),
        ),
        SizedBox(height: 8),
        Container(
          height: 30,
          child: Text(
            name,
            style: TextStyle(color: Colors.white, fontSize: 12),
            textAlign: TextAlign.center,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ],
    );
  }

2.构建图片布局 ******

Dart 复制代码
Widget _buildImageLayout(List<String> images, {double imageSize = 40}) {

    int count = images.length; //图片个数

    if (count == 1) {
      // 单个图片居中显示
      return Container(
        height: imageSize,
        width: imageSize,
        decoration: BoxDecoration(
          color: Color(0xFF55596D),
          borderRadius: BorderRadius.circular(imageSize / 2),
        ),
        child: Center(
          child: Image.asset(
            images[0],
            width: imageSize * 0.5,
            height: imageSize * 0.5,
          ),
        ),
      );
    } else if (count == 2) {

      // 两个图片交叠显示
      double overlap = imageSize * 0.2; // 交叠宽度
      double totalWidth = imageSize * 2 - overlap;

      return Container(
        width: totalWidth,
        child: Stack(
          children: [
            // 第一个图片在左边
            Positioned(
              top: 55,
              left: 0,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[0],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第二个图片在右边,交叠一部分
            Positioned(
              top: 55,
              left: imageSize - overlap,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[1],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
          ],
        ),
      );
    } else if (count == 3) {
      // 三个图片交叠显示
      double overlap = imageSize * 0.2; // 交叠宽度
      double totalWidth = imageSize + (imageSize - overlap) * 2;

      return Container(
        width: totalWidth,
        child: Stack(
          children: [
            // 第一个图片在最左边
            Positioned(
              top:55,
              left: 0,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[0],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第二个图片在中间
            Positioned(
              top:55,
              left: imageSize - overlap,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[1],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第三个图片在最右边
            Positioned(
              top:55,
              left: (imageSize - overlap) * 2,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[2],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
          ],
        ),
      );
    }

    return SizedBox.shrink();
  }
}

3.使用子项构建表格

Dart 复制代码
  Widget buildInAudioList() {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 10, vertical: 40),
      child: GridView.count(
        crossAxisCount: 2,
        crossAxisSpacing: 15,
        mainAxisSpacing: 5,
        childAspectRatio: 155 / 180,
        shrinkWrap: true,
        children: [
          _buildInAudioItem(
            name: "苹果",
            images: ["assets/images/apple.png"],
            onTap: () => print("点击苹果"),
          ),
          _buildInAudioItem(
            name: "苹果+香蕉",
            images: ["assets/images/apple.png", "assets/images/banana.png"],
            onTap: () => print("点击苹果+香蕉"),
          ),
          _buildInAudioItem(
            name: "苹果、香蕉、樱桃",
            images: ["assets/images/apple.png", "assets/images/banana.png", "assets/images/cherry.png"],
            onTap: () => print("点击苹果、香蕉、樱桃"),
          ),
          _buildInAudioItem(
            name: "苹果",
            images: ["assets/images/apple.png"],
            onTap: () => print("苹果"),
          ),
        ],
      ),
    );
  }

代码实例

Dart 复制代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFF060618),
              Color(0xFF070A23),
            ],
          ),
        ),
        child: buildInAudioList(),
      ),
    );
  }

  Widget buildInAudioList() {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 10, vertical: 40),
      child: GridView.count(
        crossAxisCount: 2,
        crossAxisSpacing: 15,
        mainAxisSpacing: 5,
        childAspectRatio: 155 / 180,
        shrinkWrap: true,
        children: [
          _buildInAudioItem(
            name: "苹果",
            images: ["assets/images/apple.png"],
            onTap: () => print("点击苹果"),
          ),
          _buildInAudioItem(
            name: "苹果+香蕉",
            images: ["assets/images/apple.png", "assets/images/banana.png"],
            onTap: () => print("点击苹果+香蕉"),
          ),
          _buildInAudioItem(
            name: "苹果、香蕉、樱桃",
            images: ["assets/images/apple.png", "assets/images/banana.png", "assets/images/cherry.png"],
            onTap: () => print("点击苹果、香蕉、樱桃"),
          ),
          _buildInAudioItem(
            name: "苹果",
            images: ["assets/images/apple.png"],
            onTap: () => print("苹果"),
          ),
        ],
      ),
    );
  }

  // 网格子项
  Widget _buildInAudioItem({
    required String name,
    required List<String> images, //用列表接收图片
    required VoidCallback onTap,
    double imageSize = 40,
  }) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        GestureDetector(
          onTap: onTap,
          child: Container(
            height: 150,
            width: 155,
            decoration: BoxDecoration(
              color: Color(0xFF1B1D2E),
              borderRadius: BorderRadius.circular(10),
            ),
            child: Center(
              child: _buildImageLayout(images, imageSize: imageSize), //传递图片和图片尺寸
            ),
          ),
        ),
        SizedBox(height: 8),
        Container(
          height: 30,
          child: Text(
            name,
            style: TextStyle(color: Colors.white, fontSize: 12),
            textAlign: TextAlign.center,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ],
    );
  }

  // 构建图片布局
  Widget _buildImageLayout(List<String> images, {double imageSize = 40}) {

    int count = images.length; //图片个数

    if (count == 1) {
      // 单个图片居中显示
      return Container(
        height: imageSize,
        width: imageSize,
        decoration: BoxDecoration(
          color: Color(0xFF55596D),
          borderRadius: BorderRadius.circular(imageSize / 2),
        ),
        child: Center(
          child: Image.asset(
            images[0],
            width: imageSize * 0.5,
            height: imageSize * 0.5,
          ),
        ),
      );
    } else if (count == 2) {
      // 两个图片交叠显示
      double overlap = imageSize * 0.2; // 交叠宽度
      double totalWidth = imageSize * 2 - overlap;

      return Container(
        width: totalWidth,
        child: Stack(
          children: [
            // 第一个图片在左边
            Positioned(
              top: 55,
              left: 0,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[0],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第二个图片在右边,交叠一部分
            Positioned(
              top: 55,
              left: imageSize - overlap,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[1],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
          ],
        ),
      );
    } else if (count == 3) {
      // 三个图片交叠显示
      double overlap = imageSize * 0.2; // 交叠宽度
      double totalWidth = imageSize + (imageSize - overlap) * 2;

      return Container(
        width: totalWidth,
        child: Stack(
          children: [
            // 第一个图片在最左边
            Positioned(
              top:55,
              left: 0,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[0],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第二个图片在中间
            Positioned(
              top:55,
              left: imageSize - overlap,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[1],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
            // 第三个图片在最右边
            Positioned(
              top:55,
              left: (imageSize - overlap) * 2,
              child: Container(
                height: imageSize,
                width: imageSize,
                decoration: BoxDecoration(
                  color: Color(0xFF55596D).withOpacity(0.8),
                  borderRadius: BorderRadius.circular(imageSize / 2),
                ),
                child: Center(
                  child: Image.asset(
                    images[2],
                    width: imageSize * 0.5,
                    height: imageSize * 0.5,
                  ),
                ),
              ),
            ),
          ],
        ),
      );
    }

    return SizedBox.shrink();
  }
}
相关推荐
传奇开心果编程5 小时前
【Flutter踩坑排雷】第3课:const 误用坑|const 错误使用引发 UI 异常与性能损耗
flutter·移动开发·跨平台·dart·编程语言理论·编程框架·声明式ui
程序员老刘7 小时前
你的Flutter项目要不要紧急升级3.47.8?
flutter·客户端
Talyra429 小时前
不想开会员,我写了一个记账 App
flutter
2601_9495758614 小时前
JSON5 跨端三方库仓颉适配全流程
前端·javascript·flutter
法的空间14 小时前
AI 编程时代,为什么 Dart 分析会拖慢大型项目的开发
android·flutter·ios
恋猫de小郭16 小时前
Flutter 紧急发布 3.47.8 安全升级版本,建议都升级
android·前端·flutter
好的佩奇1 天前
Dart 之模式
android·flutter·dart
淡淡的香烟1 天前
Flutter实现多语言切换
android·flutter·1024程序员节
事圆则缓2 天前
从零搭建一套 Flutter 架构:先跑通数据流
flutter
程序员老刘2 天前
Flutter版本选择指南:3.44稳定了11周正式转正 | 2026年10月
flutter·ai编程·客户端