esu
esu

Reputation: 2450

How to add the widgets dynamically to column in Flutter?

I have added a few widgets inside the ListView. So that I can scroll all widgets. Now I required to add one more widget to the ListView to load the list of comments. I can not add the ListView inside the ListView. And moreover, I do not require the separate scroll for my comments. It should be scroll along with the widgets inside the ListView. So I planned to add the Column instead of ListView. Could any help to add my comments dynamically in the Columns?

new Expanded(
          child:
          new ListView(
            shrinkWrap: true,
            children: <Widget>[

              // Title

              new Padding(padding: const EdgeInsets.only(
                  top: 10.00, left: 10.00),
                child: new Text(
                  _feed.title, textAlign: TextAlign.start,),
              ),

              // content

              new Container(
                child: new Text(
                  _feed.content, textAlign: TextAlign.start,),
              ),

              // Comments List will go here

            ],
          ),
        ),

Upvotes: 33

Views: 64485

Answers (7)

user1209216
user1209216

Reputation: 7984

Another way:

return Column(
      children: [
        for(String item in list) Text(item);

    ]);

You can also mix static and dynamic fields eaisly in this case:

return Column(
          children: [
            for(String item in list) Text(item),
          Text("Static text control"),
   
        ]);

Upvotes: 18

Prajeet Naga
Prajeet Naga

Reputation: 233

Yes you can add dynamic child on column widgets.

 class CategoriesItemWidget extends StatelessWidget {
  final List<String> list;

  const CategoriesItemWidget({Key? key, required this.list})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: list
          .map((string) => Text(string))
          .toList(),
    );
  }
}

Upvotes: 1

PotatoChips
PotatoChips

Reputation: 300

Currently(2021-06), Flutter 2.x implemented null-safe. The answer from @Gene Bo should work but needs little modification.

This should work.

var pwdWidgets = <Widget>[];

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: this.pwdWidgets,
),

ElevatedButton(
  onPressed: (){
    setState((){
      this.pwdWidgets.add(Text("Hello World"),);
    });
  },
  child: Text("click me"),
),

Upvotes: 6

Emmanuel Edwards
Emmanuel Edwards

Reputation: 169

In Addition to @Derek Lakin's Answer which worked for me too, it is also required to call setState(), if you need to update the comments and reload.

var commentWidgets = List<Widget>();
for (var comment in comments) {
      commentWidgets.Add(Text(comment.text)); // TODO: Whatever layout you need foreach widget.
}
setState(() {

});

Upvotes: 1

Gene Bo
Gene Bo

Reputation: 12103

By maintaining a reference to the Column object, the .children field/property can be referenced after the Column object has been declared - like so:

Column someColumn = Column(
  children: [],
);

someColumn.children.add(Text('Hello 123'));

Upvotes: 7

M. Arslan Hafeez
M. Arslan Hafeez

Reputation: 131

import 'package:flutter/material.dart';

class LoginRegisterPage extends StatefulWidget {
  @override
  _LoginRegisterPageState createState() => _LoginRegisterPageState();
}

class _LoginRegisterPageState extends State<LoginRegisterPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text("App"),
      ),
      body: new Container(
        margin: EdgeInsets.all(15.0),
        child: new Form(
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: createInputs() + createButtons(),
          ),
          ),
      ),
    );
  } 

  List<Widget> createInputs(){
    return{
      SizedBox(height: 10.0),
      logo(),
      SizedBox(height: 20.0),
      new TextFormField(
        decoration: new InputDecoration(labelText: 'Email'),
      ),

      SizedBox(height: 10.0),
      new TextFormField(
        decoration: new InputDecoration(labelText: 'Passwors')
      ),
      SizedBox(height: 20.0), 
    };
  }

  Widget logo(){
      return new Hero(        
        tag:'hero',
        child: new CircleAvatar(
          backgroundColor:Colors.transparent,
          radius: 110.0,
          child: Image.asset("images\logo.PNG"),          
        ),         
        );
    }

    List<Widget> createButtons(){
    return{
      new RaisedButton(
        child: new Text("Login", style: new TextStyle(fontSize: 20.0),),
        textColor: Colors.pink,         
        onPressed: () {          
        },
        ),  

        new FlatButton(
        child: new Text("Already not have an account?", style: new TextStyle(fontSize: 14.0),),
        textColor: Colors.white,         
        onPressed: () {
        }, 
        )  
    };
  }
}

Upvotes: 0

Derek Lakin
Derek Lakin

Reputation: 16319

If you have the comments data already, simply create a List, then pass it to the children property of the Column. Something like:

var commentWidgets = List<Widget>();
for (var comment in comments) {
  commentWidgets.Add(Text(comment.text)); // TODO: Whatever layout you need for each widget.
}
…

new Expanded(
      child:
      new ListView(
        shrinkWrap: true,
        children: <Widget>[

          // Title

          new Padding(padding: const EdgeInsets.only(
              top: 10.00, left: 10.00),
            child: new Text(
              _feed.title, textAlign: TextAlign.start,),
          ),

          // content

          new Container(
            child: new Text(
              _feed.content, textAlign: TextAlign.start,),
          ),

          // Comments List will go here
          Column(children: commentWidgets,),
        ],
      ),
    ),

If you don't have the comments data already and need to fetch it, use a FutureBuilder to build the UI once the future completes.

Upvotes: 43

Related Questions