Flutter: Building a Cupertino Picker that shows rows containing 2 widgets, from looping through a Map
You can copy paste run full code below
You can use control-flow-collections
code snippet
children: <Widget>[
for (var i = 0;
i < BuildingProblem.problemListIcons.length;
i++)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[i],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[i],
style: TextStyle(color: Colors.white70),
),
)
],
),
],
working demo
You need to add file analysis_options.yaml to root of your project and the following line
analyzer:
enable-experiment:
- control-flow-collections
full code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class BuildingProblem {
static List<Icon> problemListIcons = [];
static List<String> problemListNames = [];
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
void initState() {
BuildingProblem.problemListIcons.add(Icon(Icons.add));
BuildingProblem.problemListIcons.add(Icon(Icons.cast));
BuildingProblem.problemListNames.add("add");
BuildingProblem.problemListNames.add("cast");
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: CupertinoPicker(
itemExtent: 40,
children: <Widget>[
for (var i = 0;
i < BuildingProblem.problemListIcons.length;
i++)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[i],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[i],
style: TextStyle(color: Colors.white70),
),
)
],
),
],
onSelectedItemChanged: (int index) {
print('good boi');
},
looping: true,
backgroundColor: Color(0xff2e3032),
),
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
MoofinTheExplorer
Someone trying to improve his workflow by learning how to code and applying the knowledge and automation I can get from it to make work more efficient.
Updated on December 16, 2022Comments
-
MoofinTheExplorer over 1 year
I've created a picker that displays a Icon and a String, next to each other. The pickers items are taken from a Map I created that contains Key: String and Value: Icon.
In my code right now, I'm using the Cupertino Picker and adding children: [ Row(Icon + String)] but that's quite bad if I want to update them.
I was trying to get a loop going to generate those rows + children but I can't figure out how.
Could someone show me the way or perhaps a more efficient way of getting this result? I'm thinking Extracting row and creating a constructor to input the icon and string, but I'm sure there's a better way...
Here's the code:
Expanded( child: CupertinoPicker( itemExtent: 40, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[0], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[0], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[1], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[1], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[2], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[2], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[3], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[3], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[4], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[4], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[5], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[5], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[6], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[6], style: TextStyle(color: Colors.white70), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ BuildingProblem.problemListIcons[7], Padding( padding: EdgeInsets.only(left: 10), child: Text( BuildingProblem.problemListNames[7], style: TextStyle(color: Colors.white70), ), ) ], ) ], onSelectedItemChanged: (int index) { print('good boi'); }, looping: true, backgroundColor: Color(0xff2e3032), ), ),
How it looks like:
-
MoofinTheExplorer over 4 yearsThis works! Could you explain to me though why I had to add the control-flow-collections? I believe Flutter gave me a notification to update SDK and that did it for me, so now it works, but I'm trying to understand your solution as well as I can so that I can learn from it.
-
chunhunghan over 4 yearscontrol-flow-collections is under experiment. In my environment , I need to do it manually. I use master channel. it's just a notice. because I did not get notification to update SDK
-
MoofinTheExplorer over 4 yearsI see, this is my first app and my first coding language so I'm trying to make sense of it all as I go!