You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中从Firebase实时数据库加载帖子并展示到ListView?

实现步骤

1. 添加依赖

在pubspec.yaml中引入Firebase实时数据库和网络图片加载相关依赖:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.15.0
  firebase_database: ^10.2.0
  cached_network_image: ^3.3.0

执行flutter pub get完成依赖安装。

2. 定义Post数据模型

创建与数据库结构匹配的模型类,简化数据转换逻辑:

class Post {
  final String postId;
  final String imageUrl;
  final String uid;
  final String uEmail;
  final String uName;

  Post({
    required this.postId,
    required this.imageUrl,
    required this.uid,
    required this.uEmail,
    required this.uName,
  });

  // 将Firebase返回的Map数据转换为Post对象
  factory Post.fromMap(String postId, Map<String, dynamic> data) {
    return Post(
      postId: postId,
      imageUrl: data['imageurl'] ?? '',
      uid: data['uid'] ?? '',
      uEmail: data['uemail'] ?? '',
      uName: data['uname'] ?? '',
    );
  }
}

3. 加载数据并构建ListView

通过监听Firebase节点获取数据,使用ListView.builder渲染列表(作用等同于Android的RecyclerView):

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const PostListScreen(),
    );
  }
}

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

  @override
  State<PostListScreen> createState() => _PostListScreenState();
}

class _PostListScreenState extends State<PostListScreen> {
  final DatabaseReference _postsRef = FirebaseDatabase.instance.ref('Posts');
  List<Post> _posts = [];
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    // 监听Posts节点数据变化,实时更新列表
    _postsRef.onValue.listen((DatabaseEvent event) {
      setState(() {
        _posts.clear();
        if (event.snapshot.value != null) {
          final postsMap = event.snapshot.value as Map<dynamic, dynamic>;
          postsMap.forEach((postId, data) {
            _posts.add(Post.fromMap(postId.toString(), data as Map<String, dynamic>));
          });
        }
        _isLoading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('帖子列表')),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: _posts.length,
              itemBuilder: (context, index) {
                final post = _posts[index];
                return ListTile(
                  leading: CachedNetworkImage(
                    imageUrl: post.imageUrl,
                    placeholder: (context, url) => const CircularProgressIndicator(),
                    errorWidget: (context, url, error) => const Icon(Icons.error),
                    width: 50,
                    height: 50,
                    fit: BoxFit.cover,
                  ),
                  title: Text(post.uName),
                  subtitle: Text(post.uEmail),
                );
              },
            ),
    );
  }
}

核心说明

  • onValue监听:实时同步Firebase数据库的Posts节点数据,数据更新时自动刷新列表,效果等同于RecyclerView的notifyDataSetChanged()
  • ListView.builder:Flutter的高效长列表组件,仅渲染可见区域的item,和RecyclerView的复用逻辑一致
  • CachedNetworkImage:替代原生Image.network,提供图片缓存、加载占位和错误状态处理,优化用户体验

内容的提问来源于stack exchange,提问作者Thaddeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:10:28