Flutter仿照微信实现九宫格头像

一、效果图

2、主要代码

c 复制代码
import 'dart:io';
import 'dart:math';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';

class ImageGrid extends StatelessWidget {
  final List<String> imageUrls; // 假设这是你的图片URL列表
  final double containerSize = 72.0; // 容器大小
  final double padding = 3.0; // 图片距离容器的宽度
  final double spacing = 2.0; // 图片之间的间隔

  ImageGrid({required this.imageUrls});

  double calculateImageWidth(int count) {
    double containerWidth = 72;
    double padding = 3;
    double gap = 2;

    if (count <= 4) {
      return (containerWidth - padding * 2 - gap) / 2;
    } else {
      return (containerWidth - padding * 2 - gap * 2) / 3;
    }
  }

  Widget _buildGrid() {
    double imageWidth = calculateImageWidth(imageUrls.length);
    int imageCount = imageUrls.length > 9 ? 9 : imageUrls.length;
    if (imageCount == 1) {
      // 一张图片铺满
      return Center(
        child: Container(
          width: containerSize,
          height: containerSize,
          child: Image.network(
            imageUrls[0],
            fit: BoxFit.cover,
          ),
        ),
      );
    } else {
      int rowCount = 1; //几行
      int firstNumber = 0; //第一行显示几个0不做特别处理
      int cellCount = 1; //几列
      if (imageCount == 2) {
        rowCount = 1;
        cellCount = 2;
      } else if (imageCount == 4 || imageCount == 6) {
        rowCount = 2;
        cellCount = imageCount == 4 ? 2 : 3;
      } else if (imageCount == 9) {
        rowCount = 3;
        cellCount = 3;
      } else if (imageCount == 3) {
        rowCount = 2;
        firstNumber = 1;
        cellCount = 2;
      } else if (imageCount == 5) {
        rowCount = 2;
        firstNumber = 2;
        cellCount = 3;
      } else if (imageCount == 7) {
        rowCount = 3;
        firstNumber = 1;
        cellCount = 3;
      } else if (imageCount == 8) {
        rowCount = 3;
        firstNumber = 2;
        cellCount = 3;
      }
      // 两张图片并排
      return Padding(
        padding: EdgeInsets.all(spacing),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            if (firstNumber != 0)
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List.generate(firstNumber, (cellIndex) {
                  return Row(
                    children: [
                      getImageWidget(cellIndex, imageWidth),
                      if (cellIndex != firstNumber - 1)
                        SizedBox(width: spacing),
                    ],
                  );
                }),
              ),
            if (firstNumber != 0 && rowCount > 1) SizedBox(height: spacing),
            ...List.generate(rowCount - (firstNumber != 0 ? 1 : 0), (rowIndex) {
              return Column(
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: List.generate(cellCount, (cellIndex) {
                      int index =
                          firstNumber + rowIndex * cellCount + cellIndex;
                      return Row(
                        children: [
                          getImageWidget(index, imageWidth),
                          if (cellIndex != cellCount - 1)
                            SizedBox(width: spacing),
                        ],
                      );
                    }),
                  ),
                  if (rowIndex != rowCount - (firstNumber != 0 ? 2 : 1))
                    SizedBox(height: spacing),
                ],
              );
            }),
          ],
        ),
      );
    }
  }

//生成 图片wrapper
  getImageWidget(int index, double width) {
    if (!imageUrls[index].contains("http")) {
      return Image.file(File(imageUrls[index]),
          width: width, height: width, fit: BoxFit.cover);
    } else {
      return CachedNetworkImage(
        imageUrl: imageUrls[index],
        width: width,
        height: width,
        fit: BoxFit.cover,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(6),
      child: Container(
        width: containerSize,
        height: containerSize,
        decoration: BoxDecoration(
          //  color: Color(0xFFEEEEEE),
          color: Color.fromARGB(255, 243, 4, 4),
          borderRadius: BorderRadius.circular(6),
        ),
        child: _buildGrid(),
      ),
    );
  }
}
相关推荐
qtj-00115 小时前
普通人在刚开始做副业时要注意哪些细节?
大数据·微信·新媒体运营·创业创新
小杨互联网15 小时前
微信第三方开放平台接入本地消息事件接口报错问题java.security.InvalidKeyException: Illegal key size
微信·微信公众号·微信第三方开放平台·第三方开放平台接入
a6953188_15 小时前
如何评估一个副业项目的可行性?
大数据·微信·创业创新
lqj_本人1 天前
flutter_鸿蒙next_Dart基础②List
flutter
lqj_本人1 天前
flutter_鸿蒙next_Dart基础①字符串
flutter
The_tuber_sadness1 天前
【Flutter】- 基础语法
flutter
helloxmg1 天前
鸿蒙harmonyos next flutter通信之BasicMessageChannel获取app版本号
flutter
2401_844137952 天前
JAVA智慧社区系统跑腿家政本地生活商城系统小程序源码
微信·微信小程序·小程序·生活·微信公众平台·微信开放平台