Reputation: 4177
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
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
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
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