FlutterFlow中如何将JSON数据传入Syncfusion日期选择器blackoutDates
FlutterFlow自定义DateRangePicker动态设置blackoutDates问题解决
我在FlutterFlow中编写了自定义DateRangePicker组件,目前SfDateRangePicker的blackoutDates使用硬编码的DateTime数组,需要替换为从传入的widget.jsonDataRaw中提取日期生成的数组。传入的JSON包含多种日期格式,但多次尝试转换均失败,原始组件代码和JSON数据如下:
原始组件代码
// Automatic FlutterFlow imports import '/backend/backend.dart'; import '/backend/schema/structs/index.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/custom_code/widgets/index.dart'; // Imports other custom widgets import '/flutter_flow/custom_functions.dart'; // Imports custom functions import 'package:flutter/material.dart'; // Begin custom widget code // DO NOT REMOVE OR MODIFY THE CODE ABOVE! import 'package:syncfusion_flutter_datepicker/datepicker.dart'; import 'package:intl/intl.dart'; import 'dart:convert'; class DateRangePicker extends StatefulWidget { const DateRangePicker({ super.key, this.width, this.height, required this.jsonDataRaw, this.simpleText, }); final double? width; final double? height; final dynamic jsonDataRaw; final String? simpleText; @override State<DateRangePicker> createState() => _DateRangePickerState(); } class _DateRangePickerState extends State<DateRangePicker> { @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Column( children: [ Text(widget.simpleText.toString()), //Text(widget.jsonDataRaw.toString()), SfDateRangePicker( view: DateRangePickerView.month, monthViewSettings: DateRangePickerMonthViewSettings( firstDayOfWeek: 1, blackoutDates: [ DateTime(2024, 03, 18), DateTime(2024, 03, 19) ]), monthCellStyle: DateRangePickerMonthCellStyle( blackoutDateTextStyle: TextStyle( color: Colors.red, decoration: TextDecoration.lineThrough), ), selectionMode: DateRangePickerSelectionMode.range, enablePastDates: false, ), ], ), )); } }
传入的JSON数据
{ "success": true, "error": null, "data": [ { "date": "01/03/2024", "iso_date": "2024-03-01T18:50:01.672Z", "utc_date": "Fri, 01 Mar 2024 18:50:01 GMT", "date_string": "Fri Mar 01 2024", "timestamp": 1709319001672, "status": "owner" }, { "date": "02/03/2024", "iso_date": "2024-03-02T18:50:01.672Z", "utc_date": "Sat, 02 Mar 2024 18:50:01 GMT", "date_string": "Sat Mar 02 2024", "timestamp": 1709405401672, "status": "owner" }, { "date": "03/03/2024", "iso_date": "2024-03-03T18:50:01.672Z", "utc_date": "Sun, 03 Mar 2024 18:50:01 GMT", "date_string": "Sun Mar 03 2024", "timestamp": 1709491801672, "status": "owner" }, { "date": "04/03/2024", "iso_date": "2024-03-04T18:50:01.672Z", "utc_date": "Mon, 04 Mar 2024 18:50:01 GMT", "date_string": "Mon Mar 04 2024", "timestamp": 1709578201672, "status": "owner" }, { "date": "11/03/2024", "iso_date": "2024-03-11T18:50:01.672Z", "utc_date": "Mon, 11 Mar 2024 18:50:01 GMT", "date_string": "Mon Mar 11 2024", "timestamp": 1710183001672, "status": "reception" }, { "date": "12/03/2024", "iso_date": "2024-03-12T18:50:01.672Z", "utc_date": "Tue, 12 Mar 2024 18:50:01 GMT", "date_string": "Tue Mar 12 2024", "timestamp": 1710269401672, "status": "reception" }, { "date": "13/03/2024", "iso_date": "2024-03-13T18:50:01.672Z", "utc_date": "Wed, 13 Mar 2024 18:50:01 GMT", "date_string": "Wed Mar 13 2024", "timestamp": 1710355801672, "status": "reception" } ] }
解决方案
推荐使用JSON中的iso_date字段来转换DateTime,因为ISO格式的日期解析最稳定。具体修改步骤:
- 在
build方法中先解析widget.jsonDataRaw,处理它可能是字符串或已解析Map的情况 - 提取
data数组,遍历每个元素解析iso_date - 过滤掉解析失败的日期,避免组件报错
修改后的完整代码
// Automatic FlutterFlow imports import '/backend/backend.dart'; import '/backend/schema/structs/index.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/custom_code/widgets/index.dart'; // Imports other custom widgets import '/flutter_flow/custom_functions.dart'; // Imports custom functions import 'package:flutter/material.dart'; // Begin custom widget code // DO NOT REMOVE OR MODIFY THE CODE ABOVE! import 'package:syncfusion_flutter_datepicker/datepicker.dart'; import 'package:intl/intl.dart'; import 'dart:convert'; class DateRangePicker extends StatefulWidget { const DateRangePicker({ super.key, this.width, this.height, required this.jsonDataRaw, this.simpleText, }); final double? width; final double? height; final dynamic jsonDataRaw; final String? simpleText; @override State<DateRangePicker> createState() => _DateRangePickerState(); } class _DateRangePickerState extends State<DateRangePicker> { @override Widget build(BuildContext context) { // 解析JSON数据并转换为DateTime数组 List<DateTime> blackoutDates = []; try { Map<String, dynamic> jsonData; // 处理jsonDataRaw可能是字符串或已解析的Map的情况 if (widget.jsonDataRaw is String) { jsonData = jsonDecode(widget.jsonDataRaw); } else { jsonData = widget.jsonDataRaw as Map<String, dynamic>; } // 提取data数组 if (jsonData['success'] == true && jsonData['data'] is List) { List<dynamic> dateList = jsonData['data']; for (var item in dateList) { if (item['iso_date'] != null) { try { DateTime date = DateTime.parse(item['iso_date']); blackoutDates.add(date); } catch (e) { // 跳过解析失败的日期 debugPrint('解析日期失败: ${item['iso_date']}, 错误: $e'); } } } } } catch (e) { debugPrint('解析JSON失败: $e'); } return Scaffold( body: Container( child: Column( children: [ Text(widget.simpleText.toString()), SfDateRangePicker( view: DateRangePickerView.month, monthViewSettings: DateRangePickerMonthViewSettings( firstDayOfWeek: 1, blackoutDates: blackoutDates), // 替换为动态生成的数组 monthCellStyle: DateRangePickerMonthCellStyle( blackoutDateTextStyle: TextStyle( color: Colors.red, decoration: TextDecoration.lineThrough), ), selectionMode: DateRangePickerSelectionMode.range, enablePastDates: false, ), ], ), )); } }
补充说明
- 代码中增加了多层异常捕获,避免因JSON格式错误或日期解析失败导致组件崩溃
- 如果想用
timestamp字段转换,可将解析部分替换为:if (item['timestamp'] != null) { try { DateTime date = DateTime.fromMillisecondsSinceEpoch(item['timestamp']); blackoutDates.add(date); } catch (e) { debugPrint('解析时间戳失败: ${item['timestamp']}, 错误: $e'); } }
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

