Flutter列表对象属性提取与Widget填充问题排查
问题修复方案
问题根源
你在initState里循环时,始终给同一个bookingCalendarModel变量赋值,循环结束后这个变量只保留了最后一个医生的配置数据。所以无论点击哪个医生项,UI都会渲染最后一个医生的信息。
修复步骤
1. 存储所有医生对应的BookingModel
首先需要用一个列表来保存每个医生对应的BookingModel,而不是单个变量:
// 在State类中定义列表 List<BookingModel> bookingModels = []; @override void initState() { super.initState(); // 将每个Doctor转换为对应的BookingModel并添加到列表 bookingModels = doctorsList.map((doctor) { return BookingModel( apptName: 'Mock Service', apptDuration: doctor.duration, bookingEnd: doctor.endHour, bookingStart: doctor.startHour, ); }).toList(); }
2. 方案一:点击医生项跳转至单独预约页面
如果需要点击医生后进入单独的预约页面,先做一个医生列表,点击时传递对应索引的BookingModel:
// 医生列表页面的build方法 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('医生列表')), body: ListView.builder( itemCount: doctorsList.length, itemBuilder: (context, index) { final doctor = doctorsList[index]; return ListTile( title: Text(doctor.name), subtitle: Text(doctor.type), leading: Image.asset(doctor.imageUrl), onTap: () { // 跳转到单独的预约页面,传递对应医生的BookingModel Navigator.push( context, MaterialPageRoute( builder: (context) => DoctorBookingPage( bookingModel: bookingModels[index], doctorName: doctor.name, ), ), ); }, ); }, ), ); } // 单独的预约页面 class DoctorBookingPage extends StatelessWidget { final BookingModel bookingModel; final String doctorName; const DoctorBookingPage({ super.key, required this.bookingModel, required this.doctorName, }); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('预约$doctorName')), body: Center( child: BookingCalendar( bookingService: bookingModel, convertStreamResultToDateTimeRanges: convertStreamResultMock, getBookingStream: getBookingStreamMock, uploadBooking: uploadBookingMock, pauseSlots: generatePauseSlots(), hideBreakTime: false, loadingWidget: const Text('获取数据中...'), uploadingWidget: const CircularProgressIndicator(), locale: 'en_US', startingDayOfWeek: CalendarDays.monday, wholeDayIsBookedWidget: const Text('全天约满!请选择其他日期'), ), ), ); } }
3. 方案二:横向列表展示所有医生的预约日历
如果你想用横向ListView同时展示所有医生的预约组件,确保bookingWidgetList已正确初始化(和步骤1的列表初始化逻辑一致),然后直接使用即可:
// State类中定义列表 List<BookingModel> bookingWidgetList = []; @override void initState() { super.initState(); bookingWidgetList = doctorsList.map((doctor) { return BookingModel( apptName: 'Mock Service', apptDuration: doctor.duration, bookingEnd: doctor.endHour, bookingStart: doctor.startHour, ); }).toList(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('预约日历')), body: Container( height: 780, child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: doctorsList.length, itemBuilder: (context, index) { return Column( children: [ Text(doctorsList[index].name), BookingCalendar( bookingService: bookingWidgetList[index], convertStreamResultToDateTimeRanges: convertStreamResultMock, getBookingStream: getBookingStreamMock, uploadBooking: uploadBookingMock, pauseSlots: generatePauseSlots(), hideBreakTime: false, loadingWidget: const Text('获取数据中...'), uploadingWidget: const CircularProgressIndicator(), locale: 'en_US', startingDayOfWeek: CalendarDays.monday, wholeDayIsBookedWidget: const Text('全天约满!请选择其他日期'), ), ], ); }, ), ), ); }
内容的提问来源于stack exchange,提问作者flutter_dev
相关产品推荐
相关产品推荐

