You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用PushNamed跳转无法读取参数,类型转换报错

解决Flutter Navigator参数类型转换错误问题

错误原因

你传递的参数是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比传递整个列表更合理:

  1. 修改第一个页面的onTap逻辑:
onTap: () {
  Navigator.of(context).pushNamed(
    '/sixth',
    arguments: services[index], // 传递当前点击的单个服务
  );
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:01:09