How to avoid overwriting a List Item when using the same name?

664 Views Asked by At

In my project the user can add and edit List Items. The Problem is, that if the user add a List item with an already existing List name, the old one gets overwritten, with the error 'Multiple widgets used the same GlobalKey'. How can I avoid that, so that the user can add multiple items with the same name?

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

There are 1 best solutions below

2
On

When the user creates an element and adds it to the list, you can check the list for an element with the same name and if it exists, add its index to its name this way there cant be two elements with the same name.

You dont need to show the index part of the name to the user if you dont want to, its just for control purposes.

If you have a search bar where the user types the name of the element he wants to access you can use auto complete to show the elements tht contains what the user is typing.