添加依赖
dependencies: flutter: sdk: flutter dio: ^5.0.0 # 请检查最新版本 flutter_staggered_grid_view: ^0.4.0
添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
go后端代码
图片存放目录
Go
// main.go
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
// 定义图片结构体
type Image struct {
URL string `json:"url"`
}
func main() {
// 创建 Gin 路由
r := gin.Default()
// 提供静态文件服务,images 文件夹中的图片文件可以通过 http://localhost:8080/images/xxx.jpg 来访问
r.Static("/images", "./assets/images")
// 设置路由,当访问 /images 时,返回图片 URL 列表
r.GET("/images-list", func(c *gin.Context) {
// 假设有一组图片 URL
images := []Image{
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
{URL: "/images/test.png"},
}
// 返回 JSON 格式的图片列表
c.JSON(http.StatusOK, images)
})
// 启动 HTTP 服务,监听 8080 端口
log.Println("Starting server at http://localhost:8080")
r.Run(":8080")
}
flutter前端代码
Dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart'; // 引入 Dio 库以处理 HTTP 请求
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; // 引入用于创建瀑布流布局的库
void main() {
runApp(MyApp()); // 运行应用并调用 MyApp 类
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '瀑布流图片展示', // 应用标题
theme: ThemeData(primarySwatch: Colors.blue), // 应用主题颜色
home: ImageScreen(), // 设置 home 页为 ImageScreen
);
}
}
// 图片项类,用于存储图片的 URL
class ImageItem {
final String url; // 图片的 URL
ImageItem({required this.url}); // 构造函数
// 从 JSON 数据创建 ImageItem 实例
factory ImageItem.fromJson(Map<String, dynamic> json) {
// 这里返回新的 ImageItem 实例,URL 前加上服务端地址
return ImageItem(url: 'http://192.168.110.148:8080${json['url']}');
}
}
// API 服务类,用于获取图片数据
class ApiService {
final Dio _dio = Dio(); // 创建 Dio 实例
// 从后端获取图片列表的异步方法
Future<List<ImageItem>> fetchImages() async {
try {
// 请求 Go 后端接口,替换为您的 Go 后端地址
final response = await _dio.get('http://192.168.110.148:8080/images-list');
// 解析响应数据并转换为 ImageItem 列表
List<ImageItem> images = (response.data as List)
.map((item) => ImageItem.fromJson(item))
.toList();
return images; // 返回图片列表
} catch (e) {
throw Exception('加载图片失败: $e'); // 捕获异常并抛出
}
}
}
// 瀑布流图片展示组件
class ImageGrid extends StatelessWidget {
final List<ImageItem> images; // 图片列表
ImageGrid({required this.images}); // 构造函数
@override
Widget build(BuildContext context) {
return StaggeredGridView.countBuilder(
crossAxisCount: 2, // 列数设置为2
itemCount: images.length, // 图片数量
itemBuilder: (context, index) => Image.network(images[index].url), // 构建每个图片项
staggeredTileBuilder: (index) => StaggeredTile.fit(1), // 瀑布流样式设置
mainAxisSpacing: 4.0, // 主轴间距
crossAxisSpacing: 4.0, // 交叉轴间距
);
}
}
// 显示图片的主屏幕
class ImageScreen extends StatefulWidget {
@override
_ImageScreenState createState() => _ImageScreenState(); // 创建状态
}
class _ImageScreenState extends State<ImageScreen> {
late Future<List<ImageItem>> futureImages; // 声明未来的图片列表
@override
void initState() {
super.initState();
futureImages = ApiService().fetchImages(); // 初始化时请求图片
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('瀑布流图片展示')), // 设置 AppBar 的标题
body: FutureBuilder<List<ImageItem>>(
future: futureImages, // 提供未来的图片列表
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// 当请求数据时显示加载指示器
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
// 如果出现错误,显示错误信息
return Center(child: Text('加载失败: ${snapshot.error}'));
} else {
// 成功获取数据,显示图片网格
return ImageGrid(images: snapshot.data!);
}
},
),
);
}
}