当在颤动中点击网格时如何导航到新页面?

Posted

技术标签:

【中文标题】当在颤动中点击网格时如何导航到新页面?【英文标题】:How to navigate to a new page when a grid is tapped in flutter? 【发布时间】:2020-05-30 19:13:08 【问题描述】:

这是来自正在开发的应用程序的代码的一部分,我已经为列表中的每个项目创建了 dart 文件,但我不知道如何在列表上提供 onpress 功能,以便它将导航到下一页

这里是代码

class GridDashboard extends StatelessWidget 
  final Items item1 = new Items(
      title: "Call",
      img: "assets/call.png");

  final Items item2 = new Items(
    title: "Message",
    img: "assets/message.png",
  );
  final Items item3 = new Items(
    title: "Music",
    img: "assets/music.png",
  );
  final Items item4 = new Items(
    title: "Navigation",
    img: "assets/navigation.png",
  );
  final Items item5 = new Items(
    title: "News",
    img: "assets/news.png",
  );
  final Items item6 = new Items(
    title: "To Do List",
    img: "assets/todolist.png",
  );

  @override
  Widget build(BuildContext context) 
    List<Items> myList = [item1, item2, item3, item4, item5, item6];
    var color = 0xff616161;
    return Flexible(
      child: GridView.count(
          childAspectRatio: 1.0,
          padding: EdgeInsets.only(left: 16, right: 16),
          crossAxisCount: 2,
          crossAxisSpacing: 18,
          mainAxisSpacing: 18,
          children: myList.map((data) 
            return Container(
              decoration: BoxDecoration(
                  color: Color(color), borderRadius: BorderRadius.circular(10)),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Image.asset(
                    data.img,
                    width: 42,
                  ),
                  SizedBox(
                    height: 14,
                  ),
                  Text(
                    data.title,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white,
                            fontSize: 16,
                            fontWeight: FontWeight.w600)),
                  ),
                  SizedBox(
                    height: 8,
                  ),
                  Text(
                    data.subtitle,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white38,
                            fontSize: 10,
                            fontWeight: FontWeight.w600)),
                  ),
                  SizedBox(
                    height: 14,
                  ),
                  Text(
                    data.event,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white70,
                            fontSize: 11,
                            fontWeight: FontWeight.w600)),
                  ),
                ],
              ),
            );
          ).toList()),
    );
  


当用户点击每个项目时,我想导航到新页面。如何导航?

【问题讨论】:

只需用 GridTile 替换您的容器,GridTile 就有一个名为 onTap 的属性。或者你可以用 InkWell 包裹 Griditem 它还有一个属性 onTao。 【参考方案1】:
    import 'package:flutter/material.dart';
    import 'package:google_fonts/google_fonts.dart';
    import 'package:flutter_app/Component/callView.dart';
    import 'package:flutter_app/Component/messageView.dart';
    import 'package:flutter_app/Component/MusicView.dart';
    import 'package:flutter_app/Component/navigationView.dart';
    import 'package:flutter_app/Component/newsView.dart';
    import 'package:flutter_app/Component/todolistView.dart';
    
    void main() 
      runApp(MyApp());
    
    class MyApp extends StatelessWidget 
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) 
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.green,
    
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          routes: 
            // When navigating to the "/" route, build the FirstScreen widget.
    
            '/call': (context) => callView(),
            '/message': (context) => messageView(),
            '/music': (context) => MusicView(),
            '/navigation': (context) => navigationView(),
            '/news': (context) => newsView(),
            '/todolist': (context) => todolistView(),
          ,
          home: GridDashboard(),
        );
      
    
    
    
   class GridDashboard extends StatelessWidget 
      final Items item1 = new Items(
          title: "Call",
          img: "assets/call.png",
          subtitle: "some thing",
          event: "some thing",
          routeName:'/call'
      );
      final Items item2 = new Items(
        title: "Message",
        img: "assets/message.png",
         subtitle: "some thing",
         event: "some thing",
        routeName:'/message'
      );
      final Items item3 = new Items(
        title: "Music",
        img: "assets/music.png",
        subtitle: "some thing",
        event: "some thing",
        routeName:'/music',
      );
      final Items item4 = new Items(
        title: "Navigation",
        img: "assets/navigation.png",
        subtitle: "some thing",
        event: "some thing",
        routeName:'/navigation',
      );
      final Items item5 = new Items(
        title: "News",
        img: "assets/news.png",
        subtitle: "some thing",
        event: "some thing",
        routeName:'/news',
      );
      final Items item6 = new Items(
        title: "To Do List",
        img: "assets/todolist.png",
        subtitle: "some thing",
        event: "some thing",
        routeName:'/todolist',
      );
    
      @override
      Widget build(BuildContext context) 
        List<Items> myList = [item1, item2, item3, item4, item5, item6];
        var color = 0xff616161;
        return Flexible(
          child: GridView.count(
              childAspectRatio: 1.0,
              padding: EdgeInsets.only(left: 16, right: 16),
              crossAxisCount: 2,
              crossAxisSpacing: 18,
              mainAxisSpacing: 18,
              children: myList.map((data) 
                return InkWell(
                    onTap: ()
                      Navigator.pushNamed(context, data.routeName);
                    ,
                    child: Container(
                      decoration: BoxDecoration(
                          color: Color(color), borderRadius: BorderRadius.circular(10)),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Image.asset(
                            data.img,
                            width: 42,
                          ),
                          SizedBox(
                            height: 14,
                          ),
                          Text(
                            data.title,
                            style: GoogleFonts.openSans(
                                textStyle: TextStyle(
                                    color: Colors.white,
                                    fontSize: 16,
                                    fontWeight: FontWeight.w600)),
                          ),
                          SizedBox(
                            height: 8,
                          ),
                          Text(
                            data.subtitle,
                            style: GoogleFonts.openSans(
                                textStyle: TextStyle(
                                    color: Colors.white38,
                                    fontSize: 10,
                                    fontWeight: FontWeight.w600)),
                          ),
                          SizedBox(
                            height: 14,
                          ),
                          Text(
                            data.event,
                            style: GoogleFonts.openSans(
                                textStyle: TextStyle(
                                    color: Colors.white70,
                                    fontSize: 11,
                                    fontWeight: FontWeight.w600)),
                          ),
                        ],
                      ),
                    )
                );
              ).toList()),
        );
      
    
    
    class Items 
      String title;
      String subtitle;
      String event;
      String img;
      String routeName;
      Items(this.title, this.subtitle, this.event, this.img,this.routeName,);
    

【讨论】:

【参考方案2】:
class GridDashboard extends StatelessWidget 
  final Items item1 = new Items(
      title: "Call",
      img: "assets/call.png");

  final Items item2 = new Items(
    title: "Message",
    img: "assets/message.png",
  );
  final Items item3 = new Items(
    title: "Music",
    img: "assets/music.png",
  );
  final Items item4 = new Items(
    title: "Navigation",
    img: "assets/navigation.png",
  );
  final Items item5 = new Items(
    title: "News",
    img: "assets/news.png",
  );
  final Items item6 = new Items(
    title: "To Do List",
    img: "assets/todolist.png",
  );

  @override
  Widget build(BuildContext context) 
    List<Items> myList = [item1, item2, item3, item4, item5, item6];
    var color = 0xff616161;
    return Flexible(
      child: GridView.count(
          childAspectRatio: 1.0,
          padding: EdgeInsets.only(left: 16, right: 16),
          crossAxisCount: 2,
          crossAxisSpacing: 18,
          mainAxisSpacing: 18,
          children: myList.map((data) 
            return GestureDetector(
              onTap: ()
                Navigator.push(context,MaterialPageRoute(builder: (context)=> *your_new_route_page*))
              ,
              child: Container(
              decoration: BoxDecoration(
                  color: Color(color), borderRadius: BorderRadius.circular(10)),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Image.asset(
                    data.img,
                    width: 42,
                  ),
                  SizedBox(
                    height: 14,
                  ),
                  Text(
                    data.title,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white,
                            fontSize: 16,
                            fontWeight: FontWeight.w600)),
                  ),
                  SizedBox(
                    height: 8,
                  ),
                  Text(
                    data.subtitle,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white38,
                            fontSize: 10,
                            fontWeight: FontWeight.w600)),
                  ),
                  SizedBox(
                    height: 14,
                  ),
                  Text(
                    data.event,
                    style: GoogleFonts.openSans(
                        textStyle: TextStyle(
                            color: Colors.white70,
                            fontSize: 11,
                            fontWeight: FontWeight.w600)),
                  ),
                ],
              ),
            )
            );
          ).toList()),
    );
  

您只需将“返回的容器在 GridView.count 中”包装在 GestureDetector 中

【讨论】:

但即使在给定网格图之后.. 在 ontap 方法中我也只能给一个项目导航到下一页。当我尝试提供第二个项目时,它不起作用。 你能显示代码吗?因为我在想你可能忘记了映射数据 你应该传递的是 data.data['title'] 嗨@Akshaygopan,您是否设法为每个项目设置,如果是,您是怎么做的?【参考方案3】:

这里是你修改后的构建方法

@override
  Widget build(BuildContext context) 
    List<Items> myList = [item1, item2, item3, item4, item5, item6];
    var color = 0xff616161;
    return Flexible(
      child: GridView.count(
          childAspectRatio: 1.0,
          padding: EdgeInsets.only(left: 16, right: 16),
          crossAxisCount: 2,
          crossAxisSpacing: 18,
          mainAxisSpacing: 18,
          children: myList.map((data) 
            return GridTile(
              child: InkResponse(
                child: Container(
                  decoration: BoxDecoration(color: Color(color), borderRadius: BorderRadius.circular(10)),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Image.asset(
                        data.img,
                        width: 42,
                      ),
                      SizedBox(
                        height: 14,
                      ),
                      Text(
                        data.title,
                        style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600)),
                      ),
                      SizedBox(
                        height: 8,
                      ),
                      Text(
                        data.subtitle,
                        style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white38, fontSize: 10, fontWeight: FontWeight.w600)),
                      ),
                      SizedBox(
                        height: 14,
                      ),
                      Text(
                        data.event,
                        style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white70, fontSize: 11, fontWeight: FontWeight.w600)),
                      ),
                    ],
                  ),
                ),
                onTap: () 
                  // Handle On Tap
                ,
              ),
            );
          ).toList()),
    );
  

InkWell 的另一种使用方式

@override
  Widget build(BuildContext context) 
    List<Items> myList = [item1, item2, item3, item4, item5, item6];
    var color = 0xff616161;
    return Flexible(
      child: GridView.count(
          childAspectRatio: 1.0,
          padding: EdgeInsets.only(left: 16, right: 16),
          crossAxisCount: 2,
          crossAxisSpacing: 18,
          mainAxisSpacing: 18,
          children: myList.map((data) 
            return InkWell(
              onTap: ()
                // Handle On Tap
              ,
              child: Container(
                decoration: BoxDecoration(color: Color(color), borderRadius: BorderRadius.circular(10)),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Image.asset(
                      data.img,
                      width: 42,
                    ),
                    SizedBox(
                      height: 14,
                    ),
                    Text(
                      data.title,
                      style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600)),
                    ),
                    SizedBox(
                      height: 8,
                    ),
                    Text(
                      data.subtitle,
                      style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white38, fontSize: 10, fontWeight: FontWeight.w600)),
                    ),
                    SizedBox(
                      height: 14,
                    ),
                    Text(
                      data.event,
                      style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.white70, fontSize: 11, fontWeight: FontWeight.w600)),
                    ),
                  ],
                ),
              ),
            );
          ).toList()),
    );
  

【讨论】:

嗨 Nilesh,这将使所有网格项目在点击时移动到同一个屏幕,有没有更好的方式每次都附加到不同的屏幕? 为此,您可以使用特定元素的索引或通过 JSON 的其他属性分隔。比如 if data['type'] == '1' 转到特定屏幕。或者使用包装小部件api.flutter.dev/flutter/widgets/Wrap-class.html 嗨@Nilesh,您可以使用上面的示例分享一个示例

以上是关于当在颤动中点击网格时如何导航到新页面?的主要内容,如果未能解决你的问题,请参考以下文章

颤动中的不同导航栏

如何在颤动的底部导航栏中添加抽屉?

每次当前选项卡在 TabBar 颤动中更改时,如何将新页面添加到导航器堆栈?

移动到其他页面时无法保持底部导航栏颤动

如何在颤动中推动替换删除整个导航堆栈?

如何使用颤动的底部导航栏导航到几个新页面?