在 Flutter 中获取值 TextEditingController 时出错

Error Get Value TextEditingController In Flutter

我想用循环从textEditingController取值,listview没有滚动时出现的问题会报错,“RangeError (index): Invalid value: Not in inclusive range 0..23 : 24", 我有 40 条记录的随机数据, 当滚动到行尾时,应用程序将 运行 正确。我想要即使我不向下滚动数据仍然可以无错误地检索。

你可以运行我的示例代码,请帮助我谢谢。

import 'dart:math';
import 'package:flutter/material.dart';

class Karyawan {
  int id;
  String nama;
  int jamKerja;

  Karyawan({this.id, this.nama,});

  Karyawan.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    nama = json['nama_karyawan'];
    jamKerja = json['jam_kerja'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['nama_karyawan'] = this.nama;
    data['jam_kerja'] = this.jamKerja;
    return data;
  }
}

List<Karyawan> _daftarKaryawan = List.generate(
  40,
      (index) => Karyawan(
    id: Random().nextInt(100),
    nama: 'test ${Random().nextInt(100)}',
  ),
);

class FormInputAbsenV3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Entry Absen"),
      ),
      body: FormEntry(listKaryawan:_daftarKaryawan)

    );
  }
}

class FormEntry extends StatefulWidget {
  final List<Karyawan> listKaryawan;
  const FormEntry({Key key, this.listKaryawan}) : super(key: key);
  @override
  _FormEntryState createState() => _FormEntryState();
}

class _FormEntryState extends State<FormEntry> {
  List karyawan = [];
  final _formKey = GlobalKey<FormState>();
  List<TextEditingController> _brutos = new List();
  List<TextEditingController> _nettos = new List();
  
  void addlistAbsen() {
    for (int i = 0; i < widget.listKaryawan.length; i++) {
      karyawan.add({
        "id": widget.listKaryawan[i].id,
        "bruto": _brutos[i].text,
        "netto": _nettos[i].text
      });
    }
    print(karyawan);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: EdgeInsets.all(5.0),
        child: Form(
          key: _formKey,
          child: Container(
            child: ListView.builder(
              itemCount: widget.listKaryawan.length,
              itemBuilder: (context,index) {
                _brutos.add(new TextEditingController());
                _nettos.add(new TextEditingController());
                return Column(
                  children: [
                    FormWidget(
                      index: index,
                      nama: widget.listKaryawan[index].nama,
                      brucon: _brutos[index],
                      netcon: _nettos[index],
                    ),
                    SizedBox(
                      height: 20.0,
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.save),
        label: Text("Save"),
        onPressed: () {
          if (_formKey.currentState.validate()) {
             addlistAbsen();
          }
        },
      ),
    );
  }
}

class FormWidget extends StatelessWidget {
  final int index;
  final String nama;
  final brucon;
  final netcon;
  FormWidget({this.index, this.nama, this.brucon, this.netcon});
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Expanded(
          child: Text("${index + 1}. ${nama}"),
        ),
        Expanded(
          child: TextFormField(
            decoration: new InputDecoration(
              labelText: "Bruto",
              fillColor: Colors.white,
              border: new OutlineInputBorder(
                borderRadius: new BorderRadius.circular(25.0),
                borderSide: new BorderSide(),
              ),
            ),
            style: new TextStyle(
              fontFamily: "Poppins",
            ),
            controller: brucon,
          ),
        ),
        SizedBox(
          width: 20.0,
        ),
        Expanded(
            child: TextFormField(
              decoration: new InputDecoration(
                labelText: "Netto",
                fillColor: Colors.white,
                border: new OutlineInputBorder(
                  borderRadius: new BorderRadius.circular(25.0),
                  borderSide: new BorderSide(),
                ),
              ),
              style: new TextStyle(
                fontFamily: "Poppins",
              ),
              controller: netcon,
            ))
      ],
    );
  }
}

不能使用ListView.builder for this and you will have to use ListView。您不能使用 ListView.builder 构造函数,因为构建器仅针对那些实际可见的子级调用。请参阅 ListView.builder

的文档

ListView.builder constructor

Creates a scrollable, linear array of widgets that are created on demand.

This constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are actually visible.

请看下面的代码:

import 'package:flutter/material.dart';
import 'dart:math';

final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: FormInputAbsenV3(),
        ),
      ),
    );
  }
}

class Karyawan {
  int id;
  String nama;
  int jamKerja;

  Karyawan({
    this.id,
    this.nama,
  });

  Karyawan.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    nama = json['nama_karyawan'];
    jamKerja = json['jam_kerja'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = Map<String, dynamic>();
    data['id'] = this.id;
    data['nama_karyawan'] = this.nama;
    data['jam_kerja'] = this.jamKerja;
    return data;
  }
}

List<Karyawan> _daftarKaryawan = List.generate(
  40,
  (index) => Karyawan(
    id: Random().nextInt(100),
    nama: 'test ${Random().nextInt(100)}',
  ),
);

class FormInputAbsenV3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Entry Absen"),
        ),
        body: FormEntry(listKaryawan: _daftarKaryawan));
  }
}

class FormEntry extends StatefulWidget {
  final List<Karyawan> listKaryawan;
  const FormEntry({Key key, this.listKaryawan}) : super(key: key);
  @override
  _FormEntryState createState() => _FormEntryState();
}

class _FormEntryState extends State<FormEntry> {
  List karyawan = [];
  final _formKey = GlobalKey<FormState>();
  List<TextEditingController> _brutos = [];
  List<TextEditingController> _nettos = [];

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < widget.listKaryawan.length; i++) {
      _brutos.add(TextEditingController());
      _nettos.add(TextEditingController());
    }
  }

  void addlistAbsen() {
    for (int i = 0; i < widget.listKaryawan.length; i++) {
      karyawan.add({
        "id": widget.listKaryawan[i].id,
        "bruto": _brutos[i].text,
        "netto": _nettos[i].text
      });
    }
    print(karyawan);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: EdgeInsets.all(5.0),
        child: Form(
          key: _formKey,
          child: Container(
            // child: ListView.builder(
            //   itemCount: widget.listKaryawan.length,
            //   itemBuilder: (context, index) {
            //     _brutos.add(new TextEditingController());
            //     _nettos.add(new TextEditingController());
            //     return Column(
            //       children: [
            //         FormWidget(
            //           index: index,
            //           nama: widget.listKaryawan[index].nama,
            //           brucon: _brutos[index],
            //           netcon: _nettos[index],
            //         ),
            //         SizedBox(
            //           height: 20.0,
            //         ),
            //       ],
            //     );
            //   },
            // ),
            child: ListView(
              children: [
                for (int index = 0; index < widget.listKaryawan.length; index++)
                  Column(
                    children: [
                      FormWidget(
                        index: index,
                        nama: widget.listKaryawan[index].nama,
                        brucon: _brutos[index],
                        netcon: _nettos[index],
                      ),
                      SizedBox(
                        height: 20.0,
                      ),
                    ],
                  ),
              ],
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.save),
        label: Text("Save"),
        onPressed: () {
          if (_formKey.currentState.validate()) {
            addlistAbsen();
          }
        },
      ),
    );
  }
}

class FormWidget extends StatelessWidget {
  final int index;
  final String nama;
  final TextEditingController brucon;
  final TextEditingController netcon;
  const FormWidget({this.index, this.nama, this.brucon, this.netcon});
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Expanded(
          child: Text("${index + 1}. ${nama}"),
        ),
        Expanded(
          child: TextFormField(
            decoration: InputDecoration(
              labelText: "Bruto",
              fillColor: Colors.white,
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(25.0),
                borderSide: BorderSide(),
              ),
            ),
            style: TextStyle(
              fontFamily: "Poppins",
            ),
            controller: brucon,
          ),
        ),
        SizedBox(
          width: 20.0,
        ),
        Expanded(
            child: TextFormField(
          decoration: InputDecoration(
            labelText: "Netto",
            fillColor: Colors.white,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(25.0),
              borderSide: BorderSide(),
            ),
          ),
          style: TextStyle(
            fontFamily: "Poppins",
          ),
          controller: netcon,
        ))
      ],
    );
  }
}

请在 initState 期间初始化您的 TextEditingControllers。

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < widget.listKaryawan.length; i++) {
      _brutos.add(new TextEditingController());
      _nettos.add(new TextEditingController());
    }
  }

然后,删除 itemBuilder 中的这些行...

_brutos.add(new TextEditingController());
_nettos.add(new TextEditingController());

注意:redisplayed/newly 显示列表项时将调用 itemBuilder。因此,您的 TextEditingControllers 列表 > 列表项。 (尝试滚动到最底部,然后向上滚动)