I am new to Flutter/Dart but I have tried a few ways to add a navigation route to a list that I assign to a grid view. It may not be the most efficient way to do it but it was the first thing that came to mind. I wanted to add an InkWell to the card and have the navigation routes passed that way. Other than that the only other solution I can think of is creating an OnTap function that iterates through the list. Currently the nav list choice is giving me an error that says that a 'future object can't be assigned to a parameter type of Navigator', which I get because it is a constant. But I tried it a few other ways and got similar results. What am I doing wrong with my current configuration and is there a better/more efficient solution?
Here is my list of choices:
class Choice {
const Choice({this.title, this.icon, this.nav});
final String title;
final IconData icon;
final Navigator nav;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'Timer', icon: Icons.timer, nav: Navigator.pushNamed(context, TestConfirmation.id)),
const Choice(title: 'Seating Chart', icon: Icons.event_seat),
const Choice(title: 'Random', icon: Icons.shuffle),
const Choice(title: 'Group Maker', icon: Icons.group_add),
const Choice(title: 'Noise Monitor', icon: Icons.hearing),
const Choice(title: 'Assign Tasks', icon: Icons.assignment_ind),
const Choice(title: 'Survey', icon: Icons.rate_review),
const Choice(title: 'Permission Slips', icon: Icons.assignment),
const Choice(title: 'Lesson Plans', icon: Icons.local_library),
const Choice(title: 'Attendance', icon: Icons.schedule),
const Choice(title: 'Gradebook', icon: Icons.insert_chart)
];
Here is my Card:
class ChoiceCard extends StatelessWidget {
const ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
@override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.subhead;
return Card(
color: Colors.white,
child: InkWell(
//onTap: choice.navigation,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Icon(choice.icon,
size: 90.0, color: textStyle.color)),
Text(choice.title, style: textStyle),
]),
),
));
}
}
You can copy paste run full code below
You can use Function
instead of Navigator
code snippet
class Choice {
String title;
IconData icon;
Function nav;
...
@override
void initState() {
choices = [
Choice(
title: 'Timer',
icon: Icons.timer,
nav: () {
Navigator.pushNamed(context, "/first");
}),
Choice(
title: 'Seating Chart',
icon: Icons.event_seat,
nav: () {
Navigator.pushNamed(context, "/second");
}),
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => HomeContent(),
'/first': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
});
}
}
class Choice {
String title;
IconData icon;
Function nav;
Choice({this.title, this.icon, this.nav});
}
class HomeContent extends StatefulWidget {
// builder
@override
_HomeContentState createState() => _HomeContentState();
}
class _HomeContentState extends State<HomeContent> {
List<Choice> choices = [];
@override
void initState() {
choices = [
Choice(
title: 'Timer',
icon: Icons.timer,
nav: () {
Navigator.pushNamed(context, "/first");
}),
Choice(
title: 'Seating Chart',
icon: Icons.event_seat,
nav: () {
Navigator.pushNamed(context, "/second");
}),
Choice(title: 'Random', icon: Icons.shuffle),
Choice(title: 'Group Maker', icon: Icons.group_add),
Choice(title: 'Noise Monitor', icon: Icons.hearing),
Choice(title: 'Assign Tasks', icon: Icons.assignment_ind),
Choice(title: 'Survey', icon: Icons.rate_review),
Choice(title: 'Permission Slips', icon: Icons.assignment),
Choice(title: 'Lesson Plans', icon: Icons.local_library),
Choice(title: 'Attendance', icon: Icons.schedule),
Choice(title: 'Gradebook', icon: Icons.insert_chart)
];
}
Widget _itemBuilderFunc(BuildContext context, int index) {
return ChoiceCard(
choice: choices[index],
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: choices.length,
itemBuilder: this._itemBuilderFunc,
padding: EdgeInsets.fromLTRB(12, 12, 12, 0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 0.75),
);
}
}
class ChoiceCard extends StatelessWidget {
const ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
@override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.subhead;
return Card(
color: Colors.white,
child: InkWell(
onTap: choice.nav,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Icon(choice.icon,
size: 90.0, color: textStyle.color)),
Text(choice.title, style: textStyle),
]),
),
));
}
}
class FirstScreen extends StatefulWidget {
@override
_FirstScreenState createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
@override
Widget build(BuildContext context) {
return Text("First Screen");
}
}
class SecondScreen extends StatefulWidget {
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
@override
Widget build(BuildContext context) {
return Text("Second Screen");
}
}