Flutter使用PushNamed跳转无法读取参数,类型转换报错
错误原因
你传递的参数是List<NsdServiceInfo>类型的服务列表,但在接收页面强制将其转为List<String>,两种类型元素不兼容,因此触发类型转换错误。
修正方案
方案1:正确接收整个服务列表
在MyHomePage6页面,先导入flutter_nsd包(需NsdServiceInfo类定义),再将参数转换为正确的类型:
修改后的MyHomePage6核心代码:
import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:australremote/screens/screen1.dart'; import 'package:convert/convert.dart'; // 新增导入,获取NsdServiceInfo类定义 import 'package:flutter_nsd/flutter_nsd.dart'; class _MyHomePage6State extends State<MyHomePage6> { @override Widget build(BuildContext context) { // 修正类型转换,同时处理空参数场景 final services = ModalRoute.of(context)?.settings?.arguments as? List<NsdServiceInfo> ?? []; // 示例:取第一个服务的信息 final targetService = services.isNotEmpty ? services.first : null; final String hostname = targetService?.hostname ?? 'Unknown Host'; final String serviceName = targetService?.name ?? 'Unknown Service'; return Scaffold( appBar: AppBar( title: const Text('Connect your DAC to your network', style: TextStyle(color: Colors.black87)), titleSpacing: 00.0, centerTitle: true, toolbarHeight: 60.2, toolbarOpacity: 0.6, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( bottomRight: Radius.circular(25), bottomLeft: Radius.circular(25)), ), elevation: 0.00, backgroundColor: Colors.transparent, ), body: SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('服务名称:$serviceName'), Text('主机地址:$hostname'), SizedBox(height: 20), TextButton( onPressed:() async{ if(targetService != null){ // 使用传递的服务主机地址发起请求 var response = await http.get(Uri.parse( "http://${targetService.hostname}/httpapi.asp?command=getStatusEx"),); if (response.statusCode == 200) { print(response.body); } else { print("请求失败,状态码: ${response.statusCode}"); } } else { print("无可用服务信息"); } }, child: Text("Next", style: TextStyle(color: Colors.grey)), ), ], ), ), ); } }
方案2:传递单个选中的服务(更符合交互逻辑)
从你的代码逻辑看,用户点击的是单个设备条目,因此传递当前选中的NsdServiceInfo比传递整个列表更合理:
- 修改第一个页面的
onTap逻辑:
onTap: () { Navigator.of(context).pushNamed( '/sixth', arguments: services[index], // 传递当前点击的单个服务 ); }
- 修改
MyHomePage6的参数接收:
class _MyHomePage6State extends State<MyHomePage6> { @override Widget build(BuildContext context) { // 转换为单个NsdServiceInfo对象,处理空参数 final service = ModalRoute.of(context)?.settings?.arguments as? NsdServiceInfo; final String hostname = service?.hostname ?? 'Unknown Host'; final String serviceName = service?.name ?? 'Unknown Service'; return Scaffold( // 其余代码同方案1,直接使用service对象即可 ); } }
关键注意点
- 参数传递和接收的类型必须严格匹配,
List<NsdServiceInfo>与List<String>元素类型不同,无法直接转换。 - 使用
as?替代as,配合??设置默认值,可避免参数为空时抛出异常,提升代码健壮性。 - 传递单个服务更符合用户点击条目的交互场景,减少不必要的数据传递。
内容的提问来源于stack exchange,提问作者Alejandro Carrasquero
相关产品推荐
相关产品推荐

