5

I'm basically creating a game where a grid is getting generated dynamically. It creates the tiles, adds them to a list and uses that list as an argument for the children parameter. What I find difficult however is combining it with fixed widgets.

Let's say on top of everything, I want a text element. The problem I now encounter is that if I assign my dynamically generated content like this:

...
children: mycontent,
...

then I have nowhere to put my hard coded widgets. I hope you know what I mean. Until now, I have solved it by creating a larget list and copying the dynamically generated elements over, and afterwards adding my hard-coded widgets:

    Widget buildTile(int counter) {
    return new GestureDetector(
      onTap: (){
        setState((){
          toggleColor(counter);
        });
      },
      child: new Container(
        color: colors[counter],
        foregroundDecoration: new BoxDecoration(
          border: new Border(),
        ),
        width: 75.0,
        height: 75.0,
        margin: new EdgeInsets.all(2.0),
      )
    );
  }

  List<Widget> buildGrid(){
    Map dimensions = {"width" : 4, "height" : 6};
    List<Widget> grid = new List<Widget>(dimensions["height"]);
    List<Widget> tiles = [];

    int counter = 0;

    for (int i = 0; i < dimensions["height"]; i++){
      tiles = [];
      for (int j = 0; j < dimensions["width"]; j++){
        tiles.add(buildTile(counter));
        counter++;
      }
      grid[i] = new Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: tiles,
      );
    }
    return grid;
  }

  List<Widget> copyElements(List<Widget> from){
    List<Widget> to = [];
    for (int i = 0; i < from.length; i++){
      to.add(from[i]);
    }
    return to;
  }

  List<Widget> buildPlayground(List<Widget> grid){
    List<Widget> playground = [];

    playground = copyElements(grid);

    playground.add(new Padding(
      padding: new EdgeInsets.all(20.0),
      child: new RaisedButton(
        color: Colors.purple,
        child: new Container(
          width: 100.0,
          child: new Center(
            child: new Text("Done", style: new TextStyle(fontSize: 20.0)),
          ),
        ),
        onPressed: (){

        }
      ),
    ));
    return playground;
  }

  @override
  build(BuildContext context){
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Game"),
      ),
      body: new Container(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: buildPlayground(buildGrid()),
        )
      ),
    );
  }

It kinda works, but is very tedious as soon as I figure out that I want to add another hard coded widget. Any suggestions for how I can address this problem? Thanks

OhMad
  • 6,871
  • 20
  • 56
  • 85
  • All flutter UI is build "dynamically" - each time `build` method is called, you build whole UI "from scratch" - new widgets are created etc., only state is preserved. So treat "hard coded" and "dynamic" widget same way. – Valentyn Shybanov Jun 01 '17 at 12:35
  • https://github.com/francesco-taioli/flutter-card-demo you can see how create element programattically – Francesco Taioli Apr 07 '18 at 14:27

2 Answers2

1

I guess this is the way to go, however you could use the GridView widget, and you could create a TileWidget instead of you buildTile function. Using GridView should clean your code, but what do you mean by hard-coded widgets ?

Hadrien Lejard
  • 5,644
  • 2
  • 21
  • 18
  • with hard-coded I mean that they are not assigned to a variable and built based on conditions (let's say in a for-loop). So for me hard-coded is if I assign them directly to the parameter without variables. I thiught about the GridView, however this would make it scrollable :/ – OhMad Jun 01 '17 at 13:46
0

You can combine the accepted answer from this question and use the spread operator, like what's below, to combine a list with another list or with singular items.

List<Widget> generatedWidgets = generateWidgetList();
List<Widget> hardCodedWidgets = hardCodeWidgetList();
Widget singleHardCodedWidget = Container(
  child: Text('some text'),
);

combinedList = [...generatedWidgets, ...hardCodedWidgets, singleHardCodedWidget];
Dharman
  • 30,962
  • 25
  • 85
  • 135