如何删除或更新列表中的选定对象?

时间:2019-02-06 12:38:34

标签: dart flutter

我制作了一个简单的flutter应用程序,有一个屏幕和一个listView,可以删除或更新列表中的数据。 但是,当我尝试更新或删除其中之一时,列表中的所有数据都被更新/删除了,我错过了什么?

我执行以下操作:

ListTile(
  title: Text(child.name.toString()),
  subtitle: Text('${child.amount}'),
  onTap: () => _onChildTap(child),
  trailing: GestureDetector(
    onTap: () { setState(() { children.remove(child); }); },
    child: Icon(Icons.delete)
  ),
)

void _onChildTap(ChildModel child) {
  double amount = 5;
  setState(() { child.amount += amount; });
}

用于更新和删除数据。

下面是我的完整代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyScreen()
    );
  }
}

class ParentModel {
  ParentModel({this.id, this.name, this.children});

  int id;
  String name;
  List<ChildModel> children;
}

class ChildModel {
  ChildModel({this.id, this.name, this.amount});

  int id;
  String name;
  double amount;
}

class MyScreen extends StatefulWidget {
  @override
  _MyScreenState createState() => _MyScreenState();
}

class _MyScreenState extends State<MyScreen> {
  List<ParentModel> _list = [];

  void _onAdd() {
    ChildModel child = ChildModel(id: 1, name: 'Child 1', amount: 1);

    List<ChildModel> children = [];
    children.add(child);

    List<ParentModel> results = [];
    results.add(ParentModel(id: 1, name: 'Parent 1', children: children));
    results.add(ParentModel(id: 2, name: 'Parent 2', children: children));
    results.add(ParentModel(id: 3, name: 'Parent 3', children: children));

    if (_list.isEmpty) {
      setState(() { _list.addAll(results); });
    }
    else{
      results.forEach((parent) {
        if (!_isExistInParentList(parent.id)) {
          setState(() { _list.add(parent); });
        }
        else {
          parent.children.forEach((child) {
            if (!_isExistInChildList(parent.id, child.id)) {
              setState(() {
                _list.firstWhere((parent) => parent.id == parent.id).children.add(child);
              });
            }
          });
        }
      });
    }
  }

  bool _isExistInParentList(int parentId) {
    for (ParentModel parent in _list) {
      if (parent.id == parentId) { return true; }
    }
    return false;
  }

  bool _isExistInChildList(int parentId, int childId) {
    for (ParentModel parent in _list) {
      if (parent.id == parentId) {
        for (ChildModel child in parent.children) {
          if (child.id == childId) {
            return true;
          }
        }
      }
    }
    return false;
  }

  void _onChildTap(ChildModel child) {
    double amount = 5;
    setState(() { child.amount += amount; });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter List'),
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.add),
              onPressed: _onAdd
          )
        ],
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
                itemCount: _list.length,
                itemBuilder: (context, index) {
                  ParentModel parent = _list[index];
                  return Column(
                    children: <Widget>[
                      ExpansionTile(
                        title: Text(parent.name),
                        initiallyExpanded: true,
                        children: _buildChildren(parent.children)
                      ),
                      SizedBox(height: 10)
                    ],
                  );
                }
            ),
          ),
        ],
      ),
    );
  }

  List<Widget> _buildChildren(List<ChildModel> children) {
    List<Widget> widgets = [];
    children.forEach((child) {
      widgets.add(
        ListTile(
          title: Text(child.name.toString()),
          subtitle: Text('${child.amount}'),
          onTap: () => _onChildTap(child),
          trailing: GestureDetector(
            onTap: () { setState(() { children.remove(child); }); },
            child: Icon(Icons.delete)
          ),
        )
      );
    });
    return widgets;
  }
}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我相信您的问题在这里:

    List<ParentModel> results = [];
    results.add(ParentModel(id: 1, name: 'Parent 1', children: children));
    results.add(ParentModel(id: 2, name: 'Parent 2', children: children));
    results.add(ParentModel(id: 3, name: 'Parent 3', children: children));

您要创建ParentModel的多个实例,但是要分配children的相同实例,因此基本上children是通过3个不同的父级共享的,如果您更新其中一个父级的子级,所有3个父母的更新方式都相同。