如何在Flutter中将导航路线添加到Card

时间:2019-10-31 07:41:40

标签: flutter

在下面的代码中,我在卡上有一个方法myMenu。轻按卡片时如何导航到另一页?这些卡中将有几张将链接到其自己的页面内容。每次我添加一个函数作为示例时,都会产生错误。我该怎么做?

import 'package:flutter/material.dart';
import 'package:tarjous_app/gridview_demo.dart';

void main(List<String> args) {
  runApp(
      new MaterialApp(home: TarjousAle(), debugShowCheckedModeBanner: false));
}

class TarjousAle extends StatefulWidget {
  @override
  _TarjousAleState createState() => _TarjousAleState();
}

class _TarjousAleState extends State<TarjousAle> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("Study Plan"),
        backgroundColor: Colors.amber,
      ),
      body: Container(
        child: GridView.count(
          crossAxisCount: 3,
          children: <Widget>[
            MyMenu(
              title: "Records",
              icon: Icons.account_balance_wallet,
              shape: Colors.brown,
            ),
            MyMenu(
              title: "Academy",
              icon: Icons.account_balance,
              shape: Colors.grey,
            ),
          ],
        ),
      ),
    );
  }
}

class MyMenu extends StatelessWidget {
  MyMenu({this.title, this.icon, this.shape});

  final String title;
  final IconData icon;
  final MaterialColor shape;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(9.0),
      child: InkWell(           
      onTap: () => Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => GridViewDemo()),
      ),
        splashColor: Colors.amberAccent,
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(
                icon,
                size: 80.0,
                color: shape,
              ),
              Text(title, style: new TextStyle(fontSize: 18.0))
            ],
          ),
        ),
      ),
    );
  }
}

在墨水池小部件中,我添加了一个适用于所有卡片的功能。但是我真正希望每张卡导航到其自己的页面。例如,记录应导航到其自己的记录页面,对于学院到学院页面也是如此

5 个答案:

答案 0 :(得分:0)

使用InkWell小部件包装卡,然后在onTap方法中定义navigator.push。

    class CardWidget extends StatelessWidget {
      final Function onTapCard;

      const CardWidget({Key key, @required this.onTapCard}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Card(
          margin: EdgeInsets.all(9.0),
          child: InkWell(
            onTap: onTapCard,
            splashColor: Colors.amberAccent,
            child: Center(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Icon(
                    icon,
                    size: 80.0,
                    color: shape,
                  ),
                  Text(title, style: new TextStyle(fontSize: 18.0))
                ],
              ),
            ),
          ),
        );
      }

}

然后我们在这里有列表

class CardList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        CardWidget(
          onTapCard: () => Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => YourSecondPage()),
          ),
        ),
        CardWidget(
          onTapCard: Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => YourThirdPage()),
          ),
        ),
      ],
    );
  }
}

答案 1 :(得分:0)

GestureDetector包裹卡,然后可以使用opnTap属性。 有关更多详细信息,Official Documentation

答案 2 :(得分:0)

请注意,要导航到某个页面,您的上下文必须包含Navigator父对象实例。因此,如果您尝试直接从MaterialApp导航,则可能会遇到问题。在这里,我不会感到惊讶,因为在thread中对此进行了很好的解释,但是如果您碰巧遇到了这一点,请牢记这一点。

已编辑以处理评论:

对于您的情况,我会做类似的事情。命名路线使您可以轻松地指定您想要卡片带您前往的路线,如果您希望同一小部件​​将您带至不同的路线,则需要执行该操作。

import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(
    new MaterialApp(
      home: TarjousAle(),
      debugShowCheckedModeBanner: false,
      routes: {
        GridViewDemo.route: (context) => GridViewDemo(),
        AnotherDemo.route: (context) => AnotherDemo(),
      },
    ),
  );
}

class TarjousAle extends StatefulWidget {
  @override
  _TarjousAleState createState() => _TarjousAleState();
}

class _TarjousAleState extends State<TarjousAle> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("Study Plan"),
        backgroundColor: Colors.amber,
      ),
      body: Container(
        child: GridView.count(
          crossAxisCount: 3,
          children: <Widget>[
            MyMenu(
              title: "Records",
              icon: Icons.account_balance_wallet,
              shape: Colors.brown,
              route: GridViewDemo.route
            ),
            MyMenu(
              title: "Academy",
              icon: Icons.account_balance,
              shape: Colors.grey,
              route: AnotherDemo.route
            ),
          ],
        ),
      ),
    );
  }
}

class MyMenu extends StatelessWidget {
  MyMenu({this.title, this.icon, this.shape, this.route});

  final String title;
  final IconData icon;
  final MaterialColor shape;
  final String route;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(9.0),
      child: InkWell(
        onTap: () => Navigator.pushNamed(context, route),
        splashColor: Colors.amberAccent,
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(
                icon,
                size: 80.0,
                color: shape,
              ),
              Text(title, style: new TextStyle(fontSize: 18.0))
            ],
          ),
        ),
      ),
    );
  }
}

class GridViewDemo extends StatelessWidget {
  static String route = '/demo';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.brown,
      appBar: AppBar(title: Text('Grid view demo')),
      body: Center(
        child: Text('Grid view demo'),
      ),
    );
  }
}

class AnotherDemo extends StatelessWidget {
  static String route = '/another';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(title: Text('Another demo')),
      body: Center(
        child: Text('Another demo'),
      ),
    );
  }
}

您可以在official docsanother docs page中详细了解导航的基础知识,如果您喜欢命名的路线,则也可以阅读。

答案 3 :(得分:0)

尝试将@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")包裹在SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height, child:YourWidget(); ) ) 中,如下所示:

Card

答案 4 :(得分:0)

您可以在构造函数中接收该页面,然后转到该页面,如下所示:

class MyMenu extends StatelessWidget {
  MyMenu({this.title, this.icon, this.shape, this.page});

  final Widget page;
  ...
}

然后,在onTap中:

onTap: () => Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => page),
)

现在您可以执行以下操作:

MyMenu(
  ...
  page: GridViewDemo1(),
),
MyMenu(
  ...
  page: GridViewDemo2(),
)