Flutter通过命名路由传递参数报错,求技术解决方案
Flutter命名路由传参编译错误修复方案
问题背景
已实现基础页面路由跳转,参考官方文档尝试通过命名路由传参时触发多个编译错误,代码及错误信息如下:
错误代码
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const Home()); } class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), routes: { '/': (context) => ItemList(), '/factfile': (context) => ItemDetails(), ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(), }, ); } } class ItemList extends StatelessWidget { ItemList({Key? key}) : super(key: key) { _stream = _reference.snapshots(); } CollectionReference _reference = FirebaseFirestore.instance.collection('example_table_name'); late Stream<QuerySnapshot> _stream; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Item List'), ), body: StreamBuilder<QuerySnapshot>( stream: _stream, builder: (BuildContext context, AsyncSnapshot snapshot) { //Check error if (snapshot.hasError) { return Center(child: Text('Some error occurred ${snapshot.error}')); } //Check if data arrived if (snapshot.hasData) { //get the data QuerySnapshot querySnapshot = snapshot.data; List<QueryDocumentSnapshot> documents = querySnapshot.docs; //Convert the documents to Maps List<Map> items = documents.map((e) => { 'name': e['name'], 'dlastupd': e['dlastupd'], 'dlastupd date': DateTime.fromMillisecondsSinceEpoch(e['dlastupd'] * 1000) }).toList(); // sort in descending date order items.sort((a, b) => b["dlastupd"].compareTo(a["dlastupd"])); //Display the list return ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { //Get the item at this index Map thisItem = items[index]; //Return the widget for the list items return ListTile( title: Text(formatDate(thisItem['dlastupd date'], [dd, '', M]) + " - " + thisItem['name']), onTap: () { Navigator.pushNamed( context, '/factfile', arguments: ScreenArguments( 'id': 'example_record_id_number', ), ); }, ); }); } //Show loader return Center(child: CircularProgressIndicator()); }, ), //Display a list // Add a FutureBuilder ); } } class ItemDetails extends StatelessWidget { const ExtractArgumentsScreen({super.key}); // !!! This line causes an error !!! static const routeName = '/extractArguments'; ItemDetails(this.itemId, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { // Extract the arguments from the current ModalRoute // settings and cast them as ScreenArguments. final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments; final DocumentReference docRef = FirebaseFirestore.instance.collection("example_table_name").doc(args.id); return Scaffold( appBar: AppBar( title: Text("Item Details"), ), body: FutureBuilder<DocumentSnapshot>( future: docRef.get(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( child: CircularProgressIndicator(), ); } else if (snapshot.hasError) { return Center( // child: Text("Error: ${snapshot.error}"), child: Text("Oh no it's an error"), ); } else { final data = snapshot.data!.data() as Map<String, dynamic>; return Center( child: Text(data["name"]), ); } }, ), ); } } class ScreenArguments { final String id; ScreenArguments(this.id); }
错误信息
lib/main.dart:118:3: Error: Getters, setters and methods can't be declared to be 'const'. Try removing the 'const' keyword. const ExtractArgumentsScreen({super.key}); // !!! This line causes an error !!! ^^^^^ lib/main.dart:117:7: Error: The non-abstract class 'ItemDetails' is missing implementations for these members: - ItemDetails.ExtractArgumentsScreen Try to either - provide an implementation, - inherit an implementation from a superclass or mixin, - mark the class as abstract, or - provide a 'noSuchMethod' implementation. class ItemDetails extends StatelessWidget { ^^^^^^^^^^^ lib/main.dart:118:9: Context: 'ItemDetails.ExtractArgumentsScreen' is defined here. const ExtractArgumentsScreen({super.key}); // !!! This line causes an error !!! ^^^^^^^^^^^^^^^^^^^^^^ lib/main.dart:38:46: Error: Too few positional arguments: 1 required, 0 given. '/factfile': (context) => ItemDetails(), ^ lib/main.dart:123:3: Context: Found this candidate, but the arguments don't match. ItemDetails(this.itemId, {Key? key}) : super(key: key); ^^^^^^^^^^^ lib/main.dart:39:62: Error: Couldn't find constructor 'ExtractArgumentsScreen'. ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(), ^^^^^^^^^^^^^^^^^^^^^^ lib/main.dart:39:9: Error: The getter 'ExtractArgumentsScreen' isn't defined for the class 'Home'. - 'Home' is from 'package:firestore_connection_test/main.dart' ('lib/main.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'ExtractArgumentsScreen'. ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(), ^^^^^^^^^^^^^^^^^^^^^^ lib/main.dart:101:27: Error: Expected an identifier, but got ''id''. Try inserting an identifier before ''id''. 'id': 'example_record_id_number', ^^^^ lib/main.dart:118:33: Error: Super-initializer formal parameters can only be used in generative constructors. Try removing 'super.'. const ExtractArgumentsScreen({super.key}); // !!! This line causes an error !!! ^^^^^ lib/main.dart:123:20: Error: 'itemId' isn't an instance field of this class. ItemDetails(this.itemId, {Key? key}) : super(key: key); ^^^^^^
修复步骤及代码
核心错误分析
- 类结构混乱:把
ExtractArgumentsScreen的构造函数写在了ItemDetails类内部,导致语法冲突 - 构造函数参数错误:
ItemDetails声明了itemId参数但未定义成员变量,且路由调用时未传参 - 参数传递语法错误:
ScreenArguments是位置参数构造,错误使用Map语法传参 - 路由配置无效:引用了不存在的
ExtractArgumentsScreen类
修复后的完整代码
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:intl/intl.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const Home()); } class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), routes: { '/': (context) => const ItemList(), '/factfile': (context) => const ItemDetails(), }, ); } } class ItemList extends StatelessWidget { const ItemList({Key? key}) : super(key: key) { _stream = _reference.snapshots(); } final CollectionReference _reference = FirebaseFirestore.instance.collection('example_table_name'); late Stream<QuerySnapshot> _stream; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Item List'), ), body: StreamBuilder<QuerySnapshot>( stream: _stream, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Center(child: Text('Some error occurred ${snapshot.error}')); } if (snapshot.hasData) { QuerySnapshot querySnapshot = snapshot.data; List<QueryDocumentSnapshot> documents = querySnapshot.docs; List<Map> items = documents.map((e) => { 'name': e['name'], 'dlastupd': e['dlastupd'], 'dlastupd date': DateTime.fromMillisecondsSinceEpoch(e['dlastupd'] * 1000), 'id': e.id, // 获取Firestore文档ID用于传参 }).toList(); items.sort((a, b) => b["dlastupd"].compareTo(a["dlastupd"])); return ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { Map thisItem = items[index]; return ListTile( title: Text('${DateFormat('dd MMM').format(thisItem['dlastupd date'])} - ${thisItem['name']}'), onTap: () { Navigator.pushNamed( context, '/factfile', arguments: ScreenArguments(thisItem['id']), // 正确传递位置参数 ); }, ); }, ); } return const Center(child: CircularProgressIndicator()); }, ), ); } } class ItemDetails extends StatelessWidget { const ItemDetails({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 从路由中提取参数 final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments; final DocumentReference docRef = FirebaseFirestore.instance.collection("example_table_name").doc(args.id); return Scaffold( appBar: AppBar( title: const Text("Item Details"), ), body: FutureBuilder<DocumentSnapshot>( future: docRef.get(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return const Center(child: Text("Oh no it's an error")); } else { final data = snapshot.data!.data() as Map<String, dynamic>; return Center(child: Text(data["name"] ?? "No name found")); } }, ), ); } } class ScreenArguments { final String id; ScreenArguments(this.id); }
额外配置说明
确保在pubspec.yaml中添加必要依赖:
dependencies: flutter: sdk: flutter cloud_firestore: ^latest_version intl: ^latest_version
内容的提问来源于stack exchange,提问作者Nibbles
相关产品推荐
相关产品推荐

