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

如何在StatefulWidget中通过Bloc展示已准备好的本地Post列表数据

Flutter Bloc 本地Post列表实现方案

前置准备

先在pubspec.yaml中添加Bloc相关依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.1.5
  bloc: ^8.1.4

1. 定义Bloc状态

abstract class PostState {}

// 加载中状态
class PostLoading extends PostState {}

// 加载成功状态,携带帖子列表数据
class PostLoaded extends PostState {
  final List<Post> posts;
  PostLoaded(this.posts);
}

// 加载失败状态
class PostError extends PostState {
  final String errorMsg;
  PostError(this.errorMsg);
}

2. 定义Bloc事件

只需要一个触发加载的事件即可:

abstract class PostEvent {}
class LoadPostEvent extends PostEvent {}

3. 实现Bloc逻辑

直接读取本地已准备好的posts列表,无需调用接口:

class PostBloc extends Bloc<PostEvent, PostState> {
  // 接收外部传入的本地帖子列表
  final List<Post> localPosts;
  
  PostBloc({required this.localPosts}) : super(PostLoading()) {
    on<LoadPostEvent>(_handleLoadPost);
  }

  void _handleLoadPost(LoadPostEvent event, Emitter<PostState> emit) async {
    try {
      // 不需要API请求,直接返回本地数据,可按需添加模拟延迟
      // await Future.delayed(const Duration(milliseconds: 200));
      emit(PostLoaded(localPosts));
    } catch (e) {
      emit(PostError(e.toString()));
    }
  }
}

4. 在StatefulWidget中集成使用

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

  @override
  State<PostListPage> createState() => _PostListPageState();
}

class _PostListPageState extends State<PostListPage> {
  late PostBloc _postBloc;

  @override
  void initState() {
    super.initState();
    // 初始化Bloc时直接传入你已经准备好的本地posts列表
    _postBloc = PostBloc(localPosts: posts);
    // 触发加载事件
    _postBloc.add(LoadPostEvent());
  }

  @override
  void dispose() {
    // 页面销毁时关闭Bloc避免内存泄漏
    _postBloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('帖子列表')),
      body: BlocBuilder<PostBloc, PostState>(
        bloc: _postBloc,
        builder: (context, state) {
          // 加载中展示加载动画
          if (state is PostLoading) {
            return const Center(child: CircularProgressIndicator());
          }
          // 加载成功展示列表
          if (state is PostLoaded) {
            return ListView.builder(
              padding: const EdgeInsets.all(12),
              itemCount: state.posts.length,
              itemBuilder: (context, index) {
                final post = state.posts[index];
                // 此处可替换为你自定义的帖子卡片UI
                return Padding(
                  padding: const EdgeInsets.only(bottom: 12),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(post.caption, style: const TextStyle(fontSize: 15)),
                      const SizedBox(height: 4),
                      Text(
                        '${post.timeAgo} · 点赞${post.likes} · 评论${post.comments} · 分享${post.shares}',
                        style: const TextStyle(color: Colors.grey, fontSize: 12),
                      ),
                      if (post.imageUrl != 'null')
                        Padding(
                          padding: const EdgeInsets.only(top: 8),
                          child: Image.network(post.imageUrl, fit: BoxFit.cover),
                        )
                    ],
                  ),
                );
              },
            );
          }
          // 加载失败展示错误提示
          if (state is PostError) {
            return Center(child: Text('加载失败:${state.errorMsg}'));
          }
          return const SizedBox.shrink();
        },
      ),
    );
  }
}

注意事项

  • 请确保你代码中的User类型、currentUser、onlineUsers变量已经提前正确定义,否则会出现编译错误。
  • 如果后续需要新增帖子点赞、增删改等交互逻辑,只需要新增对应的Bloc事件,在Bloc中修改本地posts列表后重新emitPostLoaded状态即可自动更新UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:12:00