当在颤动中点击网格时如何导航到新页面?
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,您可以使用上面的示例分享一个示例以上是关于当在颤动中点击网格时如何导航到新页面?的主要内容,如果未能解决你的问题,请参考以下文章