Flutter:删除List中< ObjectWidget>索引正确但无效的元素< Widget>

inkz8wg9  于 2022-12-19  发布在  Flutter
关注(0)|答案(1)|浏览(98)

我有一个对象的列表,对象中有一个小部件。List<Object>可以添加或删除对象。当我删除此列表中的对象时,此对象中的值是正确的。但此对象中的小部件不正确。为什么?对象中的小部件应该属于此对象。这应该是正确的。如何修复此问题?
示例代码:尝试添加一个字段2次,并键入第一个字段的名称,第二个字段为“A”和“B”,然后删除第一个字段(“A”应被删除)。字段的其余部分将显示“A”。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Scaffold(body: Center(child: MyWidget())));
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Testpage();
  }
}

class Testpage extends StatefulWidget {
  const Testpage({Key? key}) : super(key: key);

  @override
  State<Testpage> createState() => _TestpageState();
}

class _TestpageState extends State<Testpage> {
  List<TestWidgetGroup> fieldList = [];

  @override
  Widget build(BuildContext context) {
    print('\nBuild\n');
    List<Widget> children = [];
    for (int index = 0; index < fieldList.length; index++) {
      print(
          '\nindex at $index, name = ${fieldList[index].object.name}, phone = ${fieldList[index].object.phone}'); // correct value
      children.add(Padding(
        padding: const EdgeInsets.all(10.0),
        child: Column(children: [
          fieldList[index].nameField,
          fieldList[index].phoneField,
          Center(
              child: TextButton(
                  onPressed: () => setState(() => fieldList.removeAt(index)),
                  child: const Text('remove'))),
        ]),
      ));
    }
    return Scaffold(
        backgroundColor: Colors.brown,
        body: SafeArea(
            child: Column(
          children: children +
              [
                Center(
                    child: TextButton(
                        onPressed: () =>
                            setState(() => fieldList.add(TestWidgetGroup())),
                        child: const Text('add')))
              ],
        )));
  }
}

class TestWidgetGroup {
  TestObject object = TestObject();
  late Widget nameField =
      buildTextField((v) => object.name = v, 'name: ${object.name}');
  late Widget phoneField =
      buildTextField((v) => object.phone = v, 'phone: ${object.phone}');
}

class TestObject {
  String? name;
  String? phone;
}

Widget buildTextField(Function(String?) onChanged, String text) {
  print(text);
  return TextFormField(onChanged: onChanged);
}
zwghvu4y

zwghvu4y1#

现在我可以使用Key来完成它。添加List<Key> fieldKeyList = [];与一个唯一的字符串。代码:

import 'package:flutter/material.dart';
import 'package:mongo_dart/mongo_dart.dart' as mongo;

class Testpage extends StatefulWidget {
  const Testpage({Key? key}) : super(key: key);

  @override
  State<Testpage> createState() => _TestpageState();
}

class _TestpageState extends State<Testpage> {
  List<TestWidgetGroup> fieldList = [];
  List<Key> fieldKeyList = [];

  @override
  Widget build(BuildContext context) {
    print('\nBuild\n');
    List<Widget> children = [];
    for (int index = 0; index < fieldList.length; index++) {
      print('\nindex at $index, name = ${fieldList[index].object.name}, phone = ${fieldList[index].object.phone}'); // correct value
      children.add(Padding(
        key: fieldKeyList[index],
        padding: const EdgeInsets.all(10.0),
        child: Column(children: [
          fieldList[index].nameField,
          fieldList[index].phoneField,
          Center(
              child: TextButton(
                  onPressed: () {
                    fieldKeyList.removeAt(index);
                    setState(() => fieldList.removeAt(index));
                  },
                  child: const Text('remove'))),
        ]),
      ));
    }
    return Scaffold(
        backgroundColor: Colors.brown,
        body: SafeArea(
            child: Column(
          children: children +
              [
                Center(
                    child: TextButton(
                        onPressed: () {
                          fieldKeyList.add(Key(mongo.ObjectId().$oid));
                          setState(() => fieldList.add(TestWidgetGroup()));
                        },
                        child: const Text('add')))
              ],
        )));
  }
}

class TestWidgetGroup {
  TestObject object = TestObject();
  late Widget nameField = buildTextField((v) => object.name = v, 'name: ${object.name}');
  late Widget phoneField = buildTextField((v) => object.phone = v, 'phone: ${object.phone}');
}

class TestObject {
  String? name;
  String? phone;
}

Widget buildTextField(Function(String?) onChanged, String text) {
  print(text);
  return TextFormField(onChanged: onChanged);
}

但是,为什么抖动使控制器删除总是删除列表的最后一个而不是目标索引?

相关问题