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

如何解决Flutter读取Firestore数据时自定义屏幕重复的问题?

问题解决:Firestore列表重复渲染固定界面元素

问题分析

你的代码中,ListView.builder的itemBuilder会为每个Firestore文档重复渲染NewWidget(包含固定标题、描述)和对应按钮,导致每个文档都附带一套完整的头部区域,出现大量重复内容与空白,不符合列表展示的预期。

解决方案

把固定的头部元素(NewWidget)从列表项构建逻辑中抽离,放在ListView.builder外部仅渲染一次;ListView只负责渲染动态的列表项(即每个文档对应的Button_Chapter_the_Articles)。

修改后的完整代码:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:operbooktest/TestMain.dart';
import 'package:operbooktest/settings_pages.dart';
import 'package:operbooktest/test3.dart';

class Checking extends StatefulWidget {
  static const String id = "Checking";

  @override
  State<Checking> createState() => _CheckingState();
}

class _CheckingState extends State<Checking> {
  Future<QuerySnapshot> getthosedocuments() async {
    QuerySnapshot snapshot = await FirebaseFirestore.instance
        .collection('testfz')
        .get();
    return snapshot;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder<QuerySnapshot>(
          future: getthosedocuments(),
          builder: (context, snapshotsub) {
            if (snapshotsub.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            }

            final docs = snapshotsub.data!.docs;
            return Column(
              children: [
                // 固定头部区域,仅渲染一次
                const NewWidget(),
                // 动态列表区域,占满剩余屏幕空间
                Expanded(
                  child: ListView.builder(
                    shrinkWrap: true,
                    physics: const ScrollPhysics(),
                    itemCount: snapshotsub.data?.size,
                    itemBuilder: (context, index) {
                      final doc = docs.elementAt(index);
                      return Center(
                        child: Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Button_Chapter_the_Articles(
                            ButtonChapterTheArticles: ((doc.data()
                            as Map<String, dynamic>)['testfield']
                            as String? ?? ""),
                            NavigatorTheChapterPageButton: const TestMain(),
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return const Column(
      children: [
        Row(
          children: [
            Flexible(
              child: Text(
                'Title',
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 24,
                  fontFamily: 'TimesNewRoman',
                  fontWeight: FontWeight.w400,
                  letterSpacing: 1,
                  height: 1.5,
                  color: Colors.black,
                ),
              ),
            ),
          ],
        ),
        SizedBox(
          height: 20,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Flexible(
              child: Text(
                'Text',
                textAlign: TextAlign.right,
                style: TextStyle(
                  fontSize: 16,
                  fontFamily: 'TimesNewRoman',
                  fontWeight: FontWeight.w400,
                  letterSpacing: 1,
                  height: 1.5,
                  color: Colors.black,
                ),
              ),
            ),
          ],
        ),
        SizedBox(
          height: 50,
        ),
        Row(
          children: [
            Flexible(
              child: Text(
                '\t\t\t\tText',
                textAlign: TextAlign.justify,
                style: TextStyle(
                  fontSize: 14,
                  fontFamily: 'TimesNewRoman',
                  fontWeight: FontWeight.w400,
                  letterSpacing: 1,
                  height: 1.3,
                  color: Colors.black,
                ),
              ),
            ),
          ],
        ),
        SizedBox(
          height: 10,
        ),
      ],
    );
  }
}

关键修改点

  • 将NewWidget移至ListView.builder外部,确保固定的标题、描述仅渲染一次。
  • 使用Column+Expanded组合布局,让列表区域自动填充剩余屏幕空间,避免布局溢出。
  • ListView仅负责渲染每个文档对应的按钮项,实现预期的列表展示效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:35:02