【问题标题】:Error Get Value TextEditingController In Flutter在 Flutter 中获取值 TextEditingController 时出错
【发布时间】:2021-04-02 12:55:43
【问题描述】:

我想用循环从 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,
            ))
      ],
    );
  }
}

【问题讨论】:

    标签: android flutter listview texteditingcontroller


    【解决方案1】:

    不能为此使用ListView.builder,您必须使用ListView。您不能使用 ListView.builder 构造函数,因为只为那些实际可见的子级调用构建器。请参阅 ListView.builder 的文档

    ListView.builder 构造函数

    创建一个可滚动的线性小部件数组,这些小部件在 需求。

    此构造函数适用于具有大(或 无限)孩子的数量,因为建造者只被要求 那些实际可见的孩子。

    请看以下代码:

    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,
            ))
          ],
        );
      }
    }
    

    【讨论】:

    • 谢谢,我试过了,但是当我在其中一个 texteditingController 中输入值时,所有值都相同,直到行尾。你能帮忙吗?
    【解决方案2】:

    请在 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());
    

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

    【讨论】:

    • 或者使用Riverpod,它可以注入一个作用域的TextEditingController,它会自动初始化并根据需要进行处理。
    • 感谢帮助我,这个问题解决了。
    猜你喜欢
    • 2020-08-01
    • 2022-01-01
    • 2019-10-06
    • 1970-01-01
    • 2022-08-16
    • 2021-06-19
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多