Flutter按日历选中日期筛选展示JSON数据及解决周历点击异常问题
问题修复方案
1. 周历点击后消失问题修复
原因是你把CalendarWeekController的初始化放在了build方法中,每次点击日期触发状态更新时,控制器会被重新创建,导致周历控件异常重置。需要把控制器改为State类的成员变量,同时把选中日期变量也移到State内部管理,点击日期时调用setState触发界面刷新即可解决。
2. 按选中日期筛选数据实现
你可以把接口返回的created字段和选中的日期都统一转为年-月-日的格式,忽略时区和具体时间部分,过滤出匹配的条目即可,同时用列表组件展示筛选后的内容,避免排版杂乱。
修改后的完整代码如下:
import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:flutter_calendar_week/flutter_calendar_week.dart'; class WeeklyData extends StatefulWidget { _WeeklyDataState createState() => _WeeklyDataState(); } class _WeeklyDataState extends State<WeeklyData> { // 把控制器和状态变量移到State内部管理,避免每次build重建 final CalendarWeekController _calendarController = CalendarWeekController(); DateTime? _selectedDt; List<dynamic> _allData = []; void fetchData() async { final uri = Uri.parse('My URL'); final header = {'Content-Type': 'application/json'}; final response = await http.get(uri, headers: header); if (response.statusCode == 200) { setState(() { _allData = json.decode(response.body); }); } } // 筛选选中日期对应的数据 List<dynamic> get _filteredData { if (_selectedDt == null || _allData.isEmpty) return []; // 统一转为年-月-日格式比对,忽略时间和时区 String targetDate = "${_selectedDt!.year}-${_selectedDt!.month.toString().padLeft(2,'0')}-${_selectedDt!.day.toString().padLeft(2,'0')}"; return _allData.where((item) { String createTime = item['created'] as String; String createDate = createTime.split('T').first; return createDate == targetDate; }).toList(); } @override void initState() { super.initState(); fetchData(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( children: [ const SizedBox( height: 20, ), CalendarWeek( controller: _calendarController, showMonth: true, height: 100, minDate: DateTime.now().add(const Duration(days: -365)), maxDate: DateTime.now().add(const Duration(days: 365)), onDatePressed: (DateTime datetime) { // 点击时更新选中日期并触发刷新 setState(() { _selectedDt = datetime; }); }, ), const SizedBox( height: 20, ), // 展示筛选后的数据,替换之前直接打印全部数据的逻辑 Expanded( child: _filteredData.isEmpty ? const Text("暂无对应日期的数据") : ListView.builder( itemCount: _filteredData.length, itemBuilder: (context, index) { var item = _filteredData[index]; return ListTile( title: Text("心情:${item['mood']}"), subtitle: Text("发布时间:${item['created']}"), // 可以根据需要自定义展示其他字段 ); }, ), ) ], ), ), ); } }
内容的提问来源于stack exchange,提问作者artistAhmed
相关产品推荐
相关产品推荐

