omer929292
omer929292

Reputation: 29

Adding widgets dynamically with flutter

I tried adding widgets dynamically using a button (Once it is pressed, a new Text widget is added to the widget tree).

It works partly, as my widget list (pwdWidgets) is updated once I press the button. However, I cannot see it on the screen whatsoever. I guess something is missing.

May someone give me a little tip to fix that?

I have attached my code

Regards

import 'package:flutter/material.dart';

class Add_Widgets extends StatefulWidget {
  @override
  _Add_WidgetsState createState() => _Add_WidgetsState();
}

class _Add_WidgetsState extends State<Add_Widgets> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: getbody(),);
  }


  var pwdWidgets = <Widget>[];

  Widget AddWidgets(){
    return MaterialButton(
        child: Text("Add", style: TextStyle(color: Colors.black)),
        onPressed: ()  {
          pwdWidgets.add(Text("Hello World!"));
          print(pwdWidgets);
        });
  }

  Widget getbody(){
    pwdWidgets=[AddWidgets()];
    return Column(children:
      pwdWidgets

      ,);
  }


}

Upvotes: 1

Views: 2772

Answers (2)

Satvik Gupta
Satvik Gupta

Reputation: 23

Okay there are basically two things you need to fix:

One is that you aren't updating the UI when you update your pwdWidgets. This can be done by setState((){});, like so:

Widget AddWidgets(){
    return MaterialButton(
        child: Text("Add", style: TextStyle(color: Colors.black)),
        onPressed: ()  {
          setState((){
          pwdWidgets.add(Text("Hello World!"));
          });
          print(pwdWidgets);
        });
  }

The other thing is that, even with setState, after every rebuild of the widget tree you initialise pwdWidgets to AddWidget, which is again just a single button. So instead, prefer to do that initialisation in initState since initState only runs once and you need this initialisation also only once.

The complete fixed code is here:

class Add_Widgets extends StatefulWidget {
  @override
  _Add_WidgetsState createState() => _Add_WidgetsState();
}

class _Add_WidgetsState extends State<Add_Widgets> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: getbody(),);
  }

  var pwdWidgets = <Widget>[];

  @override
  initState(){
     pwdWidgets=[AddWidgets()];
    super.initState();
    
  }
  Widget AddWidgets(){
    return MaterialButton(
        child: Text("Add", style: TextStyle(color: Colors.black)),
        onPressed: ()  {
          setState((){pwdWidgets.add(Text("Hello World!"));});
          
          print(pwdWidgets);
        });
  }

  Widget getbody(){
   return Column(children:
      pwdWidgets,
    );
  }
}

Upvotes: 2

Nagulan S
Nagulan S

Reputation: 752

The widget is updated in the widget tree because the value of the variable is changed but the UI is not re-rendered for that change to reflect.

Setstate will solve this.

  Widget AddWidgets(){
    return MaterialButton(
        child: Text("Add", style: TextStyle(color: Colors.black)),
        onPressed: ()  {
          pwdWidgets.add(Text("Hello World!"));
          setState(() { pwdWidgets=pwdWidgets; });
          print(pwdWidgets);
        });
  }

Edit:

Even after setsate it didn't work. Because each time the UI is rendered you are initializing the pwdWidgets back to only AddWidgets() here:

pwdWidgets=[AddWidgets()];

So I made quite a few changes in getbody() with two columns.

class Add_Widgets extends StatefulWidget {
  @override
  _Add_WidgetsState createState() => _Add_WidgetsState();
}

class _Add_WidgetsState extends State<Add_Widgets> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: getbody(),);
  }


  var pwdWidgets = <Widget>[];

  Widget AddWidgets(){
    return MaterialButton(
        child: Text("Add", style: TextStyle(color: Colors.black)),
        onPressed: ()  {
          pwdWidgets.add(Text("Hello World!"));
          setState(() {
            pwdWidgets=pwdWidgets;
          });
          print(pwdWidgets);
        });
  }

  Widget getbody(){
    return Column(children:[
      AddWidgets(),
      Column(
        children:pwdWidgets,
      )
    ]
      ,);
  }
}

Upvotes: 0

Related Questions