Ошибка получения значения TextEditingController во флаттере

Я хочу получить значение из textEditingController с помощью цикла, проблема, возникающая, когда список не прокручивается, приведет к ошибке «RangeError (index): Invalid value: не в инклюзивном диапазоне 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,
            ))
      ],
    );
  }
}
0
0
1 030
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы НЕ МОЖЕТЕ использовать 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, все значения одинаковы до конца строки. вы можете помочь?

sky developer 24.12.2020 01:01

Пожалуйста, инициализируйте свои TextEditingControllers во время initState.

  @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 с ограниченной областью действия, который автоматически инициализируется и удаляется по мере необходимости.

Randal Schwartz 24.12.2020 02:53

спасибо за помощь, эта проблема решена.

sky developer 24.12.2020 03:39

Другие вопросы по теме