更新日历样式
This commit is contained in:
@@ -3,8 +3,11 @@ import 'package:get/get.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/common/util/requestWithLog.dart';
|
||||
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
|
||||
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
|
||||
import 'package:vbvs_app/controller/date/CalendarController.dart';
|
||||
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
|
||||
import 'SleepdateWidget.dart';
|
||||
|
||||
class SleepCalendarWidget extends StatefulWidget {
|
||||
@@ -12,9 +15,11 @@ class SleepCalendarWidget extends StatefulWidget {
|
||||
final ValueChanged<DateTime>? onDateSelected;
|
||||
final int? type; // 新增参数,默认日历类型为日
|
||||
final Color highlightColor; // ✅ 新增
|
||||
final String? mac;
|
||||
|
||||
const SleepCalendarWidget({
|
||||
super.key,
|
||||
this.mac,
|
||||
this.timestamp,
|
||||
this.onDateSelected,
|
||||
this.type = 1,
|
||||
@@ -27,27 +32,89 @@ class SleepCalendarWidget extends StatefulWidget {
|
||||
|
||||
class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
CalendarController calendarController = Get.find();
|
||||
|
||||
RxMap sleepDate = <String, dynamic>{}.obs;
|
||||
RxList showLabel = <dynamic>[
|
||||
{"level": 5, "name": "无报告", "color": "#9E9E9E"}
|
||||
].obs;
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// final initialDate = widget.timestamp != null
|
||||
// ? DateTime.fromMillisecondsSinceEpoch(widget.timestamp!)
|
||||
// : DateTime.now();
|
||||
// calendarController.displayedMonth.value = initialDate;
|
||||
// calendarController.selectedDate.value = initialDate;
|
||||
// }
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final initialDate = widget.timestamp != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(widget.timestamp!)
|
||||
: DateTime.now();
|
||||
calendarController.displayedMonth.value = initialDate;
|
||||
calendarController.selectedDate.value = initialDate;
|
||||
|
||||
// 初始化请求
|
||||
fetchDate(initialDate);
|
||||
|
||||
// 每当月份变化时,重新请求数据
|
||||
ever(calendarController.displayedMonth, (DateTime newMonth) {
|
||||
fetchDate(newMonth);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchDate(DateTime timeStamp) async {
|
||||
final dateStr = timeStamp.toString().split(' ')[0];
|
||||
|
||||
await requestWithLog(
|
||||
logTitle: "查询睡眠报告",
|
||||
method: MyHttpMethod.get,
|
||||
queryUrl:
|
||||
"https://sleepdata.he-info.com/api/analysis/sleep/analysis?mac=${widget.mac}&time=$dateStr&type=3",
|
||||
onSuccess: (res) {
|
||||
sleepDate.value = res.data;
|
||||
showLabel.value = [
|
||||
...res.data['scoreList']['type'],
|
||||
{"level": 5, "name": "无报告", "color": "#9E9E9E"},
|
||||
// ✅ 注意拼写是 scoreList
|
||||
];
|
||||
},
|
||||
onFailure: (res) {
|
||||
sleepDate.value = {};
|
||||
showLabel.value = [
|
||||
{"level": 5, "name": "无报告", "color": "#9E9E9E"},
|
||||
];
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> fetchSleepColor(DateTime timeStamp) async {
|
||||
final dateStr = timeStamp.toString().split(' ')[0];
|
||||
|
||||
await requestWithLog(
|
||||
logTitle: "查询睡眠报告",
|
||||
method: MyHttpMethod.get,
|
||||
queryUrl: "https://sleepdata.he-info.com/api/analysis/sleep/score/type",
|
||||
onSuccess: (res) {
|
||||
sleepDate.value = res.data;
|
||||
showLabel.value = [
|
||||
...res.data['scoreList']['type'],
|
||||
{"level": 5, "name": "无报告", "color": "#9E9E9E"},
|
||||
// ✅ 注意拼写是 scoreList
|
||||
];
|
||||
},
|
||||
onFailure: (res) {
|
||||
sleepDate.value = {};
|
||||
showLabel.value = [
|
||||
{"level": 5, "name": "无报告", "color": "#9E9E9E"},
|
||||
];
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Map<String, dynamic>> showLabel = [
|
||||
{"level": 1, "name": "优秀", "color": Color(0xFF4CAF50)},
|
||||
{"level": 2, "name": "良好", "color": Color(0xFF8BC34A)},
|
||||
{"level": 3, "name": "合格", "color": Color(0xFFFFC107)},
|
||||
{"level": 4, "name": "注意", "color": Color(0xFFF44336)},
|
||||
{"level": 5, "name": "无报告", "color": Color(0xFF9E9E9E)},
|
||||
];
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
@@ -117,7 +184,7 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendarBody(List<Map<String, dynamic>> showLabel) {
|
||||
Widget _buildCalendarBody(List<dynamic> showLabel) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
constraints: BoxConstraints(minHeight: 720.rpx),
|
||||
@@ -135,9 +202,8 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
children: [
|
||||
// 仅当为日历模式显示周标题
|
||||
_buildWeekdayHeader(),
|
||||
// 日历日期格子,支持日和周的高亮逻辑
|
||||
|
||||
_buildCalendarGrid(calendarRows, selectedDate),
|
||||
// 日历日期格子,支持日和周的高亮逻辑sleep
|
||||
_buildCalendarGrid(calendarRows, selectedDate, sleepDate.value),
|
||||
// TODO: 你可以扩展 month 类型的展示
|
||||
SizedBox(height: 55.rpx),
|
||||
_buildLegend(showLabel),
|
||||
@@ -169,8 +235,8 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendarGrid(
|
||||
List<List<DateTime>> calendarRows, DateTime? selectedDate) {
|
||||
Widget _buildCalendarGrid(List<List<DateTime>> calendarRows,
|
||||
DateTime? selectedDate, Map sleepDate) {
|
||||
final isMonthSelected = widget.type == 3;
|
||||
|
||||
Widget content = Column(
|
||||
@@ -197,6 +263,7 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
return Expanded(
|
||||
child: SleepdateWidget(
|
||||
highlightColor: widget.highlightColor, // ✅ 传入高亮颜色
|
||||
sleepDate: sleepDate,
|
||||
date: date,
|
||||
isSelected: isSelected,
|
||||
onTap: () {
|
||||
@@ -257,7 +324,7 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildLegend(List<Map<String, dynamic>> showLabel) {
|
||||
Widget _buildLegend(List showLabel) {
|
||||
return Wrap(
|
||||
spacing: 20.rpx,
|
||||
runSpacing: 20.rpx,
|
||||
@@ -271,7 +338,7 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
||||
width: 20.rpx,
|
||||
height: 20.rpx,
|
||||
decoration: BoxDecoration(
|
||||
color: item["color"],
|
||||
color: stringToColor(item["color"]),
|
||||
borderRadius: BorderRadius.circular(10.rpx),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
|
||||
|
||||
class SleepdateWidget extends StatelessWidget {
|
||||
@@ -7,17 +8,90 @@ class SleepdateWidget extends StatelessWidget {
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
final Color highlightColor; // 新增
|
||||
|
||||
const SleepdateWidget({
|
||||
super.key,
|
||||
final Map sleepDate;
|
||||
SleepdateWidget({
|
||||
required this.sleepDate,
|
||||
required this.date,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
this.highlightColor = Colors.black, // 默认值黑色
|
||||
});
|
||||
|
||||
@override
|
||||
// Widget build(BuildContext context) {
|
||||
// return ClickableContainer(
|
||||
// onTap: onTap,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// highlightColor: Colors.transparent,
|
||||
// padding: EdgeInsets.all(4.rpx),
|
||||
// child: Container(
|
||||
// width: 90.rpx,
|
||||
// height: 90.rpx,
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(30.rpx),
|
||||
// color: isSelected ? highlightColor : Colors.transparent, // 使用传入的颜色
|
||||
// ),
|
||||
// child: Padding(
|
||||
// padding:
|
||||
// EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx),
|
||||
// child: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Color(0xFF757575),
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// alignment: Alignment.center,
|
||||
// child: Text(
|
||||
// '${date.day}',
|
||||
// style: TextStyle(
|
||||
// color: Colors.white,
|
||||
// fontSize: 26.rpx,
|
||||
// letterSpacing: 0.0,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color? fillColor;
|
||||
|
||||
// 判断是否存在 score 数据
|
||||
final List<dynamic>? dataList = sleepDate['scoreList']?['data'];
|
||||
final List<dynamic>? typeList = sleepDate['scoreList']?['type'];
|
||||
|
||||
if (dataList != null && typeList != null) {
|
||||
// 查找是否有匹配日期的数据
|
||||
for (var item in dataList) {
|
||||
final st = item['st'];
|
||||
final level = item['level'];
|
||||
|
||||
if (st is int) {
|
||||
final itemDate =
|
||||
DateTime.fromMillisecondsSinceEpoch(st).toLocal(); // 转为本地时间
|
||||
|
||||
// 判断是否是同一天
|
||||
if (itemDate.year == date.year &&
|
||||
itemDate.month == date.month &&
|
||||
itemDate.day == date.day) {
|
||||
// 找到对应 level 的颜色
|
||||
final matchType = typeList.firstWhere(
|
||||
(e) => e['level'] == level,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (matchType != null && matchType['color'] != null) {
|
||||
final hexColor = matchType['color'];
|
||||
fillColor = stringToColor(hexColor);
|
||||
}
|
||||
|
||||
break; // 找到就跳出
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ClickableContainer(
|
||||
onTap: onTap,
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -28,14 +102,14 @@ class SleepdateWidget extends StatelessWidget {
|
||||
height: 90.rpx,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.rpx),
|
||||
color: isSelected ? highlightColor : Colors.transparent, // 使用传入的颜色
|
||||
color: isSelected ? highlightColor : Colors.transparent,
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF757575),
|
||||
color: fillColor ?? Color(0xFF757575), // 如果匹配不到就默认灰色
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
|
||||
Reference in New Issue
Block a user