使用相同名称时如何避免覆盖列表项?

Posted

技术标签:

【中文标题】使用相同名称时如何避免覆盖列表项?【英文标题】: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);
                  ),
            );
          ),
    );
  


【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

谢谢,我该如何实现呢?我尝试了不同的方法,但没有奏效 计划[i] = 名称;您在哪里添加新计划对吗?如果是这样,您可以添加一个控制字符,然后在列表中添加计划的索引,如下所示 plans[i] = name + 'C' + i.index.toString();它应该创建像“Plan AC0”这样的东西,当你想向用户展示它时,你知道全名,但会显示除控制字符以外的所有内容。

以上是关于使用相同名称时如何避免覆盖列表项?的主要内容,如果未能解决你的问题,请参考以下文章

如何在屏幕上设置两个相同大小的RecyclerView,保持高度换行内容以避免空白

如何使用列表项的名称创建函数,

避免将重复项添加到 listview android

合并两个数组,并且把相同的数值覆盖掉

从多个指标(相同的标签集,不同的名称)绘制 rate() 时如何避免“向量不能包含具有相同标签集的指标”错误

如何“保存”列表或如何避免列表被覆盖? [复制]