Warm tip: This article is reproduced from stackoverflow.com, please click
dart flutter

Is there a way to add a navigation route to list in Flutter/Dart?

发布于 2020-03-29 12:45:47

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),
                ]),
          ),
        ));
  }
}
Questioner
Part_Time_Nerd
Viewed
44
chunhunghan 2020-01-31 16:11

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

enter image description here

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");
  }
}