Flutter/Dart中如何访问方法内变量构建ListView组件
报错根因
message是getMessages()函数内部声明的局部变量,作用域仅限函数内部,build方法无法访问该变量- 接口请求为异步逻辑,拿到数据后没有调用状态更新方法通知Flutter重绘UI
ListView.builder直接放入Column子组件中没有做高度约束,运行时会触发垂直方向布局溢出错误
修复方案
- 在
_messageBoardState类中声明成员变量存储消息列表,初始化空数组 - 接口请求拿到
message数据后,通过setState给成员变量赋值,触发UI刷新 - 给
ListView.builder外层包裹Expanded组件,适配Column的布局规则 - 增加类型兼容处理,避免字段类型不匹配导致的渲染报错
修复后的完整可运行代码:
import 'dart:convert'; import 'dart:io'; import 'package:cache_manager/cache_manager.dart'; import 'package:flutter/material.dart'; import 'package:hong_leong_mockup_v6/request/response.dart'; import 'package:http/http.dart' as http; class messageBoard extends StatefulWidget { messageBoard({Key? key}) : super(key: key); @override State<messageBoard> createState() => _messageBoardState(); } class _messageBoardState extends State<messageBoard> { // 声明成员变量存储消息列表,初始为空 List message = []; getMessages() async { var newMessage = await (ReadCache.getString(key: 'cache1')); var response = await http.get( Uri.parse( 'http://192.168.1.8:8080/HongLeong/MENU_REQUEST.do?_dc=1657717579436&table_id=25018&id_MenuAction=3&reset_context=1&ViewType=MENU_REQUEST&gui_open_popup=1&id_Window=5&activeWindowId=mw_5&noOrigUserDate=true&LocalDate=20220713&LocalTime=21061900&TimeZone=Asia/Shanghai&UserDate=0&UserTime=0&server_name=OPRISK_DATACOLLECTOR&key_id_list=&cell_context_id=0&id_Desktop=100237&operation_key=1000007&operation_sub_num=-1&is_json=1&is_popup=0&is_search_window=0&ccsfw_conf_by_user=0&is_batch=0&previousToken=1657717554097&historyToken=1657717579434&historyUrl=1'), headers: {HttpHeaders.cookieHeader: newMessage}, ); ResponseModel responseModel = ResponseModel.fromJson(jsonDecode(response.body)); var resMessage = responseModel.response.genericListAnswer.listNode .map((x) => x.toJson()['field'][0]['field_value']) .toList(); print(resMessage); // 拿到数据后更新状态,触发UI重绘 setState(() { message = resMessage; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: Column( children: [ // 用Expanded包裹ListView,适配Column布局 Expanded( child: ListView.builder( itemCount: message.length, itemBuilder: (context, index) { return ListTile( title: Text(message[index].toString()), ); }), ), Center( child: TextButton( style: ButtonStyle( foregroundColor: MaterialStateProperty.all<Color>(Colors.blue), ), onPressed: getMessages, child: const Text('获取留言'), ), ) ], ), ); } }
开发建议
- 类名推荐使用大驼峰命名,
messageBoard建议修改为MessageBoard,符合Dart官方开发规范 - 如果需要页面打开就自动加载留言,可以在
initState生命周期中调用getMessages()方法,无需手动点击按钮触发 - 接口请求建议增加异常捕获逻辑,避免请求失败时应用崩溃
内容的提问来源于stack exchange,提问作者JoshuaaMarkk
相关产品推荐
相关产品推荐

