Flutter中使用onTap实现Card点击跳转新页面报错如何解决
报错原因
- 语法错误:首页第一个卡片的
GestureDetector包裹逻辑写错,多了一层错误的括号,把组件和属性错误地包成了记录式结构,不符合Dart语法规范;同时给被GestureDetector包裹的Material加了const修饰,父组件是非常量组件的情况下子组件不能用常量构造,会触发编译错误。 - 跳转目标缺失:代码里写的跳转目标
analgesicos()是不存在的类/方法,路由跳转需要传入提前定义好的页面Widget实例,未定义直接调用会报未找到标识符的错误。 - 依赖缺失:启动页里用
Platform.isIOS判断平台时,没有导入dart:io标准库,会触发Platform类未定义的错误。 - 属性传值错误:
TextStyle里的fontFamily属性只需要传入pubspec.yaml中配置的字体家族名称,不需要传入字体文件的完整路径,你写的fonts/Quicksand-Light.ttf属于资产路径,不是合法的字体家族名,会导致字体加载失败。
修复方案
- 第一步:在代码最顶部补全需要导入的依赖库
import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';
- 第二步:提前定义好需要跳转的目标页面,以镇痛剂分类页为例,基础页面结构如下,其他分类页面可以参照这个结构创建
class AnalgesicosPage extends StatelessWidget { const AnalgesicosPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.teal, centerTitle: true, title: const Text( 'Analgésicos', style: TextStyle(fontFamily: 'Quicksand', fontSize: 22), ), ), body: const Center(child: Text('此处放置镇痛剂类药物的学习内容')), ); } }
- 第三步:修正首页卡片的
GestureDetector包裹写法,去掉多余括号和错误的const修饰,把跳转目标替换为你创建好的页面类;同时修正所有TextStyle里的fontFamily传值,确保字体配置正确。 - 第四步:如果需要给其他卡片也加点击跳转,参照第一个卡片的写法给每个Card外层包裹
GestureDetector,或者直接用InkWell组件实现自带水波纹效果的点击即可。
修复后完整可运行代码
import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Farmacologia Odontológica', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: const Splash(), ); } } class Splash extends StatefulWidget { const Splash({super.key}); @override State<Splash> createState() => _SplashState(); } class _SplashState extends State<Splash> { @override void initState() { super.initState(); Future.delayed(const Duration(seconds: 2), () { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const HomePage())); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.teal, body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'icons/Pilulas.png', height: 230, width: 230, ), const SizedBox(height: 30), if (Platform.isIOS) const CupertinoActivityIndicator( radius: 15, ) else const CircularProgressIndicator( color: Colors.white, ) ], ), ), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.teal, centerTitle: true, title: const Text( 'Farmacologia Odontológica', style: TextStyle(fontFamily: 'Quicksand', fontSize: 22), ), ), body: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Padding(padding: EdgeInsets.only(top: 10, bottom: 10)), const Text( 'Classes de Medicamentos', textAlign: TextAlign.center, style: TextStyle(fontFamily: 'Quicksand', fontSize: 18), ), // 修复后的可点击镇痛剂卡片 GestureDetector( onTap: () => Navigator.push( context, MaterialPageRoute(builder: (context) => const AnalgesicosPage()), ), child: const Material( child: Card( child: ListTile( title: Text('Analgésicos'), ), ), ), ), // 其他卡片后续可参照上面的写法加点击跳转 const Material( child: Card( child: ListTile( title: Text('Anti-inflamatórios'), ), ), ), const Material( child: Card( child: ListTile( title: Text('Antibióticos'), ), ), ), const Material( child: Card( child: ListTile( title: Text('Antifúngicos'), ), ), ), const Material( child: Card( child: ListTile( title: Text('Antivirais'), ), ), ), const Material( child: Card( child: ListTile( title: Text('Anti-histamínicos'), ), ), ), const Material( child: Card( child: ListTile( title: Text('Ansiolíticos'), ), ), ) ], ), ), ); } } // 跳转目标页面示例 class AnalgesicosPage extends StatelessWidget { const AnalgesicosPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.teal, centerTitle: true, title: const Text( 'Analgésicos', style: TextStyle(fontFamily: 'Quicksand', fontSize: 22), ), ), body: const Center( child: Text('此处放置镇痛剂类药物的学习内容'), ), ); } }
注意:如果要使用自定义字体,需要提前把字体文件放到项目对应目录,并且在pubspec.yaml中完成字体的注册配置,否则字体会不生效。
内容的提问来源于stack exchange,提问作者Pedro Henrique Cesar
相关产品推荐
相关产品推荐

