【问题标题】:How to avoid overwriting a List Item when using the same name?使用相同名称时如何避免覆盖列表项?
【发布时间】:2021-08-25 18:26:04
【问题描述】:

在我的项目中,用户可以添加和编辑列表项。问题是,如果用户添加一个具有现有列表名称的列表项,旧的会被覆盖,并出现错误“多个小部件使用相同的 GlobalKey”。我怎样才能避免这种情况,以便用户可以添加多个具有相同名称的项目?

import 'package:flutter/material.dart';

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

  @override
  _PlanOverviewState createState() => _PlanOverviewState();
}

class _PlanOverviewState extends State<PlanOverview> {
  List<String> plans = ['Plan A', 'Plan B'];

  void addPlan(String newPlan) {
    setState(() {
      plans.add(newPlan);
    });
    Navigator.of(context).pop();
  }

  void newEntry() {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            content: TextField(
              onSubmitted: addPlan,
              decoration: InputDecoration(
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10)),
                  icon: Icon(Icons.text_snippet_outlined),
                  labelText: 'Name des Plans'),
            ),
          );
        });
  }

  void edit(int i) => showDialog(
      context: context,
      builder: (context) {
        final plan = plans[i];

        return AlertDialog(
            content: TextFormField(
                decoration: InputDecoration(
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(10)),
                    icon: Icon(Icons.text_snippet_outlined)),
                initialValue: plan,
                onFieldSubmitted: (_) => Navigator.of(context).pop(),
                onChanged: (name) => setState(
                      () {
                        plans[i] = name;
                      },
                    )));
      });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Trainingspläne'),
        shape: RoundedRectangleBorder(
          borderRadius:
          BorderRadius.only(bottomLeft: Radius.circular(10.0), bottomRight: Radius.circular(10.0)),
        ),
        actions: [
          IconButton(
            onPressed: newEntry,
            icon: Icon(Icons.add),
          ),
        ],
      ),
      body: ReorderableListView.builder(
          itemCount: plans.length,
          onReorder: (oldi, newi) => setState(() {
                final i = newi > oldi ? newi - 1 : newi;
                final plan = plans.removeAt(oldi);
                plans.insert(i, plan);
              }),
          itemBuilder: (context, i) {
            final plan = plans[i];

            return ListTile(
              tileColor: Color.fromARGB(255, 34, 34, 34),
              key: ValueKey(plan),
              contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
              title: Text(plans[i]),
              onTap: () {
                Navigator.push<Widget>(
                    context,
                    MaterialPageRoute(
                        builder: (context) =>
                            ExerciseTable(key: GlobalKey(), title: plans[i])));
              },
              trailing: IconButton(
                  icon: Icon(Icons.edit),
                  onPressed: () {
                    edit(i);
                  }),
            );
          }),
    );
  }
}

【问题讨论】:

    标签: list flutter dart listview reorderable-list


    【解决方案1】:

    当用户创建一个元素并将其添加到列表中时,您可以检查列表中是否存在具有相同名称的元素,如果存在,则将其索引添加到其名称中,这样就不能有两个具有相同名称的元素.

    如果你不想,你不需要向用户显示名称的索引部分,它只是为了控制目的。

    如果您有一个搜索栏,用户可以在其中输入他想要访问的元素的名称,您可以使用自动完成功能来显示包含用户输入内容的元素。

    【讨论】:

    • 谢谢,我该如何实现呢?我尝试了不同的方法,但没有奏效
    • 计划[i] = 名称;您在哪里添加新计划对吗?如果是这样,您可以添加一个控制字符,然后在列表中添加计划的索引,如下所示 plans[i] = name + 'C' + i.index.toString();它应该创建像“Plan AC0”这样的东西,当你想向用户展示它时,你知道全名,但会显示除控制字符以外的所有内容。
    猜你喜欢
    • 2021-12-18
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2014-07-05
    • 2021-11-10
    相关资源
    最近更新 更多