flutter - Extracting widget set state - index - Stack Overflow

admin2025-04-16  5

I need help here with my code. After extracting the EditButton Widget, the page does not update the edit icon value. Everything is fine without extracting the widget.

Also, is there a Visual Studio Code plugin, or any other simple and easy way to extract the widgets with setstates, listview builders, etc.?

class HomeScreen extends StatefulWidget {
  const HomeScreen({
    super.key,
  });

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late TextEditingController textInputTitle;
  late TextEditingController textInputContent;
  late TextEditingController textInputAuthor;

  @override
  void initState() {
    textInputTitle = TextEditingController();
    textInputContent = TextEditingController();
    textInputAuthor = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    textInputTitle.dispose();
    textInputContent.dispose();
    textInputAuthor.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          ListView.builder(
            shrinkWrap: true,
            itemCount: question.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(question[index].animalTitle),
                subtitle: Text(question[index].AnimalDetails),
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    IconButton(onPressed: () {}, icon: Icon(Icons.add)),
                    EditButton(
                        index: index,
                        textInputTitle: textInputTitle,
                        textInputContent: textInputContent),
                  ],
                ),
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) {
                        return AnimalDetails(
                          questionDetails: question[index],
                        );
                      },
                    ),
                  );
                },
              );
            },
          ),
        ],
      ),
    );
  }
}



class EditButton extends StatefulWidget {
  final int index;
  const EditButton({
    super.key,
    required this.textInputTitle,
    required this.textInputContent,
    required this.index,
  });

  final TextEditingController textInputTitle;
  final TextEditingController textInputContent;

  @override
  State<EditButton> createState() => _EditButtonState();
}

class _EditButtonState extends State<EditButton> {
  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () {
        showDialog<String>(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: const Text('AlertDialog Title'),
              content: Column(
                children: [
                  TextField(
                    controller: widget.textInputTitle,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].animalTitle)),
                  ),
                  TextField(
                    controller: widget.textInputContent,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].AnimalDetails)),
                  ),
                ],
              ),
              actions: <Widget>[
                TextButton(
                  onPressed: () {
                    Navigator.pop(context, 'Cancel');
                  },
                  child: const Text('Cancel'),
                ),
                TextButton(
                  onPressed: () {
                    setState(
                      () {
                        question[widget.index].animalTitle =
                            widget.textInputTitle.text;
                        question[widget.index].AnimalDetails =
                            widget.textInputContent.text;
                      },
                    );

                    Navigator.pop(context, 'OK');
                  },
                  child: const Text('OK'),
                ),
              ],
            );
          },
        );
      },
      icon: Icon(Icons.edit),
    );
  }
}

I need help here with my code. After extracting the EditButton Widget, the page does not update the edit icon value. Everything is fine without extracting the widget.

Also, is there a Visual Studio Code plugin, or any other simple and easy way to extract the widgets with setstates, listview builders, etc.?

class HomeScreen extends StatefulWidget {
  const HomeScreen({
    super.key,
  });

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late TextEditingController textInputTitle;
  late TextEditingController textInputContent;
  late TextEditingController textInputAuthor;

  @override
  void initState() {
    textInputTitle = TextEditingController();
    textInputContent = TextEditingController();
    textInputAuthor = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    textInputTitle.dispose();
    textInputContent.dispose();
    textInputAuthor.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          ListView.builder(
            shrinkWrap: true,
            itemCount: question.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(question[index].animalTitle),
                subtitle: Text(question[index].AnimalDetails),
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    IconButton(onPressed: () {}, icon: Icon(Icons.add)),
                    EditButton(
                        index: index,
                        textInputTitle: textInputTitle,
                        textInputContent: textInputContent),
                  ],
                ),
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) {
                        return AnimalDetails(
                          questionDetails: question[index],
                        );
                      },
                    ),
                  );
                },
              );
            },
          ),
        ],
      ),
    );
  }
}



class EditButton extends StatefulWidget {
  final int index;
  const EditButton({
    super.key,
    required this.textInputTitle,
    required this.textInputContent,
    required this.index,
  });

  final TextEditingController textInputTitle;
  final TextEditingController textInputContent;

  @override
  State<EditButton> createState() => _EditButtonState();
}

class _EditButtonState extends State<EditButton> {
  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () {
        showDialog<String>(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: const Text('AlertDialog Title'),
              content: Column(
                children: [
                  TextField(
                    controller: widget.textInputTitle,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].animalTitle)),
                  ),
                  TextField(
                    controller: widget.textInputContent,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].AnimalDetails)),
                  ),
                ],
              ),
              actions: <Widget>[
                TextButton(
                  onPressed: () {
                    Navigator.pop(context, 'Cancel');
                  },
                  child: const Text('Cancel'),
                ),
                TextButton(
                  onPressed: () {
                    setState(
                      () {
                        question[widget.index].animalTitle =
                            widget.textInputTitle.text;
                        question[widget.index].AnimalDetails =
                            widget.textInputContent.text;
                      },
                    );

                    Navigator.pop(context, 'OK');
                  },
                  child: const Text('OK'),
                ),
              ],
            );
          },
        );
      },
      icon: Icon(Icons.edit),
    );
  }
}
Share Improve this question edited Feb 26 at 21:36 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Feb 4 at 4:38 melearningmelearning 831 silver badge7 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The problem is that the HomeScreen never gets a setState after the questions are changed. One way to do it is to give the EditButton the setState function of the parent. You could do that like this for example

class EditButton extends StatefulWidget {
  final int index;
  const EditButton({
    super.key,
    required this.textInputTitle,
    required this.textInputContent,
    required this.index,
    required this.parentSetState,
  });

  final TextEditingController textInputTitle;
  final TextEditingController textInputContent;
  final Function (VoidCallback) parentSetState;

  @override
  State<EditButton> createState() => _EditButtonState();
}

class _EditButtonState extends State<EditButton> {
  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () {
        showDialog<String>(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: const Text('AlertDialog Title'),
              content: Column(
                children: [
                  TextField(
                    controller: widget.textInputTitle,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].animalTitle)),
                  ),
                  TextField(
                    controller: widget.textInputContent,
                    decoration: InputDecoration(
                        label: Text(question[widget.index].AnimalDetails)),
                  ),
                ],
              ),
              actions: <Widget>[
                TextButton(
                  onPressed: () {
                    Navigator.pop(context, 'Cancel');
                  },
                  child: const Text('Cancel'),
                ),
                TextButton(
                  onPressed: () {
                    widget.parentSetState(
                          () {
                        question[widget.index].animalTitle =
                            widget.textInputTitle.text;
                        question[widget.index].AnimalDetails =
                            widget.textInputContent.text;
                      },
                    );

                    Navigator.pop(context, 'OK');
                  },
                  child: const Text('OK'),
                ),
              ],
            );
          },
        );
      },
      icon: Icon(Icons.edit),
    );
  }
}

and then where you add the button

EditButton(
    index: index,
    textInputTitle: textInputTitle,
    textInputContent: textInputContent,
    parentSetState: setState),

It's probably not the best way to do it, but it should work regardless. Ideally you want to use some state management methods like Provider. It also seems that question is a static variable which also isn't the best code practice. But it isn't that easy to simply explain in an answer so you might want to research that by yourself. In any case for a simple application my answer is maybe good enough.

转载请注明原文地址:http://www.anycun.com/QandA/1744740371a86945.html