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

Flutter页面间传递Article ID实现单篇文章查看及错误解决

Flutter Firestore文章列表跳转单篇页面错误修复

我通过Model类从Firestore获取文章列表并用ListView展示,希望用户点击View按钮时,把对应文章的ID传到单篇文章页面展示内容,但Navigator跳转环节出错,相关代码和错误截图如下:

错误截图


问题原因分析

  • 列表页面跳转时使用了未定义的article.id变量,实际应该用列表中当前项的ID
  • 单篇文章页面未接收传递的ID参数,无法获取目标文章标识
  • 单篇页面直接使用未定义的变量渲染UI,且错误地获取整个文章列表而非单篇数据

修复后的列表页面代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:neerogi/screens/Articles/Admin/viewOne_articles.dart';

import '../articlesModel.dart';

class ViewArticlesScreens extends StatefulWidget {
  const ViewArticlesScreens({Key? key}) : super(key: key);

  @override
  State<ViewArticlesScreens> createState() => _ViewArticlesScreensState();
}

class _ViewArticlesScreensState extends State<ViewArticlesScreens> {
  Future<List<Articles>> fetchRecords() async {
    var records = await FirebaseFirestore.instance.collection('articles').get();
    return mapRecords(records);
  }

  List<Articles> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
    var _list = records.docs
        .map(
          (article) => Articles(
            id: article.id,
            topic: article['topic'],
            description: article['description'],
            url: article['url'],
          ),
        )
        .toList();

    return _list;
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Column(
        children: [
          SingleChildScrollView(
            child: Column(
              children: <Widget>[
                const SizedBox(height: 10),
                SizedBox(
                    width: width * 0.94,
                    height: height * 0.90,
                    child: FutureBuilder<List<Articles>>(
                        future: fetchRecords(),
                        builder: (context, snapshot) {
                          if (snapshot.hasError) {
                            return Text('Error: ${snapshot.error}');
                          } else if (!snapshot.hasData) {
                            return const Center(child: CircularProgressIndicator());
                          } else {
                            List<Articles> data = snapshot.data ?? [];

                            return ListView.builder(
                                itemCount: data.length,
                                itemBuilder: (context, index) {
                                  final currentArticle = data[index];
                                  return SizedBox(
                                    height: 100,
                                    child: Column(
                                      children: <Widget>[
                                        ListTile(
                                            leading: Image.network(
                                              currentArticle.url,
                                              height: 30,
                                              fit: BoxFit.cover,
                                            ),
                                            title: Text(currentArticle.topic),
                                            subtitle:
                                                Text(currentArticle.description),
                                            trailing: ElevatedButton(
                                              child: const Text('View'),
                                              onPressed: () {
                                                Navigator.of(context).push(
                                                    MaterialPageRoute(
                                                        builder: (context) =>
                                                            ViewOneArticleScreen(
                                                              articleId: currentArticle.id,
                                                            )));
                                              },
                                            ))
                                      ],
                                    ),
                                  );
                                });
                          }
                        }))
              ],
            ),
          ),
        ],
      ),
    );
  }
}

修复后的单篇文章页面代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import '../articlesModel.dart';

class ViewOneArticleScreen extends StatefulWidget {
  final String articleId;
  const ViewOneArticleScreen({Key? key, required this.articleId}) : super(key: key);

  @override
  State<ViewOneArticleScreen> createState() => _ViewOneArticleScreenState();
}

class _ViewOneArticleScreenState extends State<ViewOneArticleScreen> {
  Future<Articles?> fetchSingleArticle() async {
    var doc = await FirebaseFirestore.instance.collection('articles').doc(widget.articleId).get();
    if (doc.exists) {
      return Articles.fromJson(doc.data()!);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;
    return Scaffold(
      body: FutureBuilder<Articles?>(
        future: fetchSingleArticle(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Center(child: Text('加载出错: ${snapshot.error}'));
          } else if (!snapshot.hasData || snapshot.data == null) {
            return const Center(child: Text('文章不存在'));
          } else {
            final article = snapshot.data!;
            return Column(
              children: [
                Image.network(
                  article.url,
                  height: 150,
                  width: double.infinity,
                  fit: BoxFit.cover,
                ),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(article.topic, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                      const SizedBox(height: 8),
                      Text(article.description),
                    ],
                  ),
                ),
              ],
            );
          }
        },
      ),
    );
  }
}

关键修复点

  1. 列表页面:将跳转参数改为currentArticle.id,确保传递当前点击项的正确ID
  2. 单篇页面:
    • 添加articleId参数接收传递的文章ID
    • 实现fetchSingleArticle方法,根据ID从Firestore获取单篇数据
    • 使用FutureBuilder处理异步加载,用获取到的文章数据渲染UI

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:05:23