Flutter跨页API传值失败,选择时区后始终显示初始德里时间如何解决
问题根因
home.dart页面build方法每次执行都会强制覆盖data为初始路由参数:data = ModalRoute.of(context)!.settings.arguments as Map;,导致选择地点后setState修改的新数据被初始的德里数据冲掉。home.dart中接收choose_location返回数据的setState逻辑存在拼写错误,将isdaytime写为isdatime,导致昼夜判断参数异常。
修复步骤
- 修改
home.dart代码:把路由参数读取逻辑移到initState生命周期中,仅在页面首次初始化时读取一次,避免每次重绘都覆盖数据,同时修正拼写错误,增加空值判断避免崩溃。
修改后的完整代码:
import 'package:flutter/material.dart'; import 'package:universal_time_app/services/universal_time.dart'; import 'dart:developer'; class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { Map data={}; @override void initState() { super.initState(); // 仅首次初始化时读取路由参数,后续不再覆盖 WidgetsBinding.instance.addPostFrameCallback((_) { data = ModalRoute.of(context)!.settings.arguments as Map; setState(() {}); }); } @override Widget build(BuildContext context) { String bgImage='Nw1.jpg'; // 昼夜判断 if (data.isNotEmpty && data['isdaytime'] == true) { bgImage = 'Dw.jpg'; } return Scaffold( body:Container( decoration: BoxDecoration( image: DecorationImage( image:AssetImage('assets/$bgImage'), fit: BoxFit.cover, ), ), child: SafeArea( child:Column( children:<Widget>[ TextButton.icon( onPressed:() async { dynamic result = await Navigator.pushNamed(context, '/location'); if(result != null) { // 空判断,避免用户点系统返回键报错 setState(() { data ={ 'time' : result['time'], 'location' : result['location'], 'isdaytime':result['isdaytime'], // 修正拼写错误 'flag': result['flag'], }; }); } }, icon:Icon(Icons.edit_location_rounded,size:45.0,color: Colors.orange,), label: Text( 'Edit Location', style: TextStyle( fontSize: 25.0, color: Colors.white, ), ), ), SizedBox(height: 230.0,), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( data['location']??'', style: TextStyle( color: Colors.yellowAccent, fontSize: 50.0, letterSpacing: 2.0, ), ), ], ), SizedBox(height: 20.0,), Text( data['time']??'', style: TextStyle( color: Colors.white, fontSize: 70.0, letterSpacing: 2.0, ), ), ], ), ), ), ); } }
- 可选优化:如果需要保留首次启动先走加载页、默认显示德里时间的逻辑,把
main.dart的initialRoute改为'/'即可,当前设置的'/location'会导致首次启动直接跳地点选择页,跳过Loading逻辑。
修改后的main.dart参考:
import 'package:flutter/material.dart'; import 'package:universal_time_app/pages/choose_location.dart'; import'package:universal_time_app/pages/home.dart'; import'package:universal_time_app/pages/loading.dart'; void main() => runApp(MaterialApp( initialRoute: '/', // 走Loading逻辑,保留首次启动默认德里时间 routes: { '/':(context)=>Loading(), '/home':(context)=>Home(), '/location':(context)=>ChooseLocation(), }, ));
内容的提问来源于stack exchange,提问作者Akai356A
相关产品推荐
相关产品推荐

