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

Flutter中如何通过循环/索引动态展示所有文本字段值?

解决方案

问题核心

你当前的问题根源在于循环调用Navigator.pushReplacement会反复替换页面,最终仅保留最后一次跳转的结果,且预览页面仅接收单个条目数据,无法承载多条动态字段内容。需要将所有动态字段的数据打包成列表一次性传递,而非逐个传递。


1. 定义数据模型类

先创建一个类封装每个动态条目的完整数据,避免零散传递:

class TimeSheetEntry {
  final String name;
  final String startTime;
  final String endTime;
  final String description;
  final String date;

  TimeSheetEntry({
    required this.name,
    required this.startTime,
    required this.endTime,
    required this.description,
    required this.date,
  });
}

2. 修改第一个页面的跳转逻辑

移除循环调用Navigator.pushReplacement的代码,改为一次性收集所有控制器数据并打包传递:

// 收集所有动态字段数据
List<TimeSheetEntry> entries = [];
for (int i = 0; i < _nameControllers.length; i++) {
  entries.add(TimeSheetEntry(
    name: _nameControllers[i].text,
    startTime: "s", // 替换为实际的startTime控制器值
    endTime: "getEndTime", // 替换为实际的endTime控制器值
    description: _descriptionControllers[i].text,
    date: "aa", // 替换为实际的日期值
  ));
}

// 仅跳转一次预览页面,传递完整条目列表
Navigator.pushReplacement(
  context,
  CupertinoPageRoute(
    builder: (context) => TimeSheetPreviewScreen(
      entries: entries,
      perHourRate: hourlyRateController.text,
      suppliesAmount: suppliesAmountController.text,
    ),
  ),
);

3. 修改预览页面的参数接收

更新TimeSheetPreviewScreen构造函数,接收条目列表并移除原有单个字段参数:

class TimeSheetPreviewScreen extends StatefulWidget {
  final List<TimeSheetEntry> entries;
  final String perHourRate;
  final String suppliesAmount;

  const TimeSheetPreviewScreen({
    Key? key,
    required this.entries,
    required this.perHourRate,
    required this.suppliesAmount,
  }) : super(key: key);

  @override
  _TimeSheetPreviewScreenState createState() => _TimeSheetPreviewScreenState();
}

4. 更新预览页面的UI展示逻辑

修改ListView.separated的数据源,通过索引遍历条目列表展示所有内容:

ListView.separated(
  physics: const BouncingScrollPhysics(),
  shrinkWrap: true,
  itemCount: widget.entries.length,
  separatorBuilder: (BuildContext context, int index) => const Divider(color: Colors.transparent),
  itemBuilder: (BuildContext context, int index) {
    final entry = widget.entries[index]; // 获取当前条目数据
    return Column(
      children: [
        Row(
          children: [
            Text("${LocaleKeys.name_txt.tr()}: ", style: myStyle),
            Text(entry.name),
          ],
        ),
        SizedBox(height: 15.h),
        Row(
          children: [
            Text("${LocaleKeys.startTime_txt.tr()}: ", style: myStyle),
            Text(entry.startTime),
          ],
        ),
        SizedBox(height: 15.h),
        Row(
          children: [
            Text("${LocaleKeys.endTime_txt.tr()}: ", style: myStyle),
            Text(entry.endTime),
          ],
        ),
        SizedBox(height: 15.h),
        Row(
          children: [
            Text("${LocaleKeys.date_txt.tr()}: ", style: myStyle),
            Text(entry.date),
          ],
        ),
        SizedBox(height: 15.h),
        Row(
          children: [
            Text("${LocaleKeys.description_txt.tr()}: ", style: myStyle),
            Text(entry.description),
          ],
        ),
        SizedBox(height: 15.h),
        Helper.customSizedBox,
        const Divider(color: Colors.grey),
      ],
    );
  },
)

5. 更新PDF生成逻辑

若需要在PDF中展示所有条目,修改PdfInvoiceApi.generate方法以接收条目列表:

// 示例:更新PDF生成方法
static Future<File> generate({
  required String weekEndingDate,
  required List<TimeSheetEntry> entries,
  required String amountBilled,
  required String invoiceNo,
}) async {
  // 生成PDF时遍历entries列表,逐个添加条目内容
  // ... 你的PDF生成逻辑
}

在预览页面的按钮点击事件中传递列表:

final pdfFile = await PdfInvoiceApi.generate(
  weekEndingDate: widget.entries.first.date, // 根据需求取日期
  entries: widget.entries,
  amountBilled: widget.perHourRate,
  invoiceNo: ControllersTextFields.instance.invoiceNoController.text,
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:27:23