Dani
Dani

Reputation: 4177

How to pass values to widgets inside an array in Flutter

I have this array/list in Flutter which contains some simple widgets:

final List<Widget> steps = [
      _step0(),
      _step1(),
      _step2(),
    ];

I can display all of them like this:

itemBuilder: (BuildContext context, int index) {
   return steps[index];
}

But how can I pass a value to one of the widget from the itemBuilder?

Widget step0 build(String something) {}

Upvotes: 4

Views: 9997

Answers (3)

MrCas
MrCas

Reputation: 61

I solved it just changing to List of Functions returning Widgets. In your case you would need to:

final List<Function> steps = [
  (input) => _step0(input),
  (input) => _step1(input),
  (input) => _step2(input),
];

Then when you loop over it you just pass the argument to the constructor as:

itemBuilder: (BuildContext context, int index) {
   return steps[index](input);
}

Upvotes: 1

Blasanka
Blasanka

Reputation: 22417

If I got you, this is what you are trying to achieve you need to have a list of Function not Widget:

class _MyHomePageState extends State<MyHomePage> {
  List<Function> steps;

  @override
  void initState() {
    steps = [
      _step0,
      _step1,
      _step2,
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: ListView.builder(
          itemCount: steps.length,
          itemBuilder: (BuildContext context, int index) {
            return steps[index](somethinng: "something");
          },
        ),
      ),
    );
  }

  Widget _step0({String somethinng}) {
    return Container(child: Text(somethinng ?? "anything"));
  }

  Widget _step1({String somethinng}) {
    return Container(child: Text(somethinng ?? "anything"));
  }

  Widget _step2({String somethinng}) {
    return Container(child: Text(somethinng ?? "anything"));
  }
}

If you can adjust your scenario to match with one method(without step0, step1, ...), you can try something like below or get an idea and do some changes to your scenario:

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: ListView(
          children: List.generate(10, (int index) {
            return ParentWidget(
              data: index,
              function: () => print("whooo! $index"),
              child: Text(index.toString(), style: TextStyle(fontSize: 20)),
            );
          }),
        ),
      ),
    );
  }
}

class ParentWidget extends StatefulWidget {
  final Widget child;
  final int data;
  final Function function;

  ParentWidget({this.child, this.data, this.function});

  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  @override
  void initState() {
    print(widget.data);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: widget.function,
      child: Container(
        child: (widget.child != null) ? widget.child : SizedBox(),
      ),
    );
  }
}

If you have large collection of data, please dont use, List.generate() use ListView.builder like you are doing right now.

If this not what you are looking for please let me know to delete this answer.

Upvotes: 4

Daniel
Daniel

Reputation: 1079

You mean something like this?:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _myListView(context);
  }
}

Widget _myListView(BuildContext context) {
  final List<Widget> steps = [
    _step0(1),
    _step1(2),
    _step2(3),
  ];

  return ListView.builder(
    itemCount: steps.length,
    itemBuilder: (BuildContext context, int index) {
      return steps[index];
    },
  );
}

_step0(int number) {
  print(number);
}

_step1(int number) {
  print(number);
}

_step2(int number) {
  print(number);
}

Upvotes: 0

Related Questions