You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现按日期重复的集市日通知功能

解决方案建议

一、核心:集市日计算逻辑

首先需要确定一个基准集市日(首次打开APP时可让用户选择最近的一次集市日,或者预设小镇的固定起始日),之后每3天循环推算。核心代码逻辑如下:

// 计算下一个(或当前)集市日
DateTime calculateNextMarketDay(DateTime baseMarketDay, DateTime currentDate) {
  DateTime nextMarket = baseMarketDay;
  // 若基准日在当前日期之前,循环加3天直到找到最近的未来/当天日期
  while (nextMarket.isBefore(currentDate)) {
    nextMarket = nextMarket.add(const Duration(days: 3));
  }
  return nextMarket;
}

把基准日存在本地避免重复设置,用SharedPreferences实现:

// 保存基准日
void saveBaseMarketDay(DateTime date) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setInt('base_market_day', date.millisecondsSinceEpoch);
}

// 获取基准日
Future<DateTime?> getBaseMarketDay() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  int? timestamp = prefs.getInt('base_market_day');
  return timestamp != null ? DateTime.fromMillisecondsSinceEpoch(timestamp) : null;
}

二、本地通知实现

用flutter_local_notifications库完成通知功能,步骤如下:

  1. 初始化通知插件
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

// 初始化配置
Future<void> initNotifications() async {
  const AndroidInitializationSettings androidSettings =
      AndroidInitializationSettings('@mipmap/ic_launcher');
  const InitializationSettings initSettings =
      InitializationSettings(android: androidSettings);
  await flutterLocalNotificationsPlugin.initialize(initSettings);
}
  1. 请求通知权限
    用户勾选checkbox时先申请权限:
Future<bool> requestNotificationPermission() async {
  if (Platform.isAndroid) {
    AndroidFlutterLocalNotificationsPlugin androidPlugin =
        flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()!;
    return await androidPlugin.requestNotificationsPermission();
  }
  // iOS 权限请求逻辑可按需添加
  return true;
}
  1. 设置定时通知
    开启通知后,计算触发时间(比如集市日当天早8点)并设置定时任务:
Future<void> scheduleMarketNotification(DateTime marketDay) async {
  // 设定通知触发时间为集市日当天8:00
  DateTime notifyTime = DateTime(
    marketDay.year,
    marketDay.month,
    marketDay.day,
    8,
    0,
  );

  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'market_notify_channel',
    '集市日提醒',
    channelDescription: '提醒你即将到来的集市日',
    importance: Importance.high,
    priority: Priority.high,
  );
  const NotificationDetails notifyDetails =
      NotificationDetails(android: androidDetails);

  await flutterLocalNotificationsPlugin.schedule(
    0, // 唯一通知ID
    '集市日提醒',
    '今天是小镇集市日,别错过啦!',
    notifyTime,
    notifyDetails,
    androidAllowWhileIdle: true, // 后台也能触发通知
  );
}
  1. 处理通知开关状态
    用SharedPreferences保存用户的通知开关状态,切换时同步开启/取消通知:
// 保存通知开关状态
void saveNotificationEnabled(bool enabled) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setBool('notification_enabled', enabled);
}

// 获取通知开关状态
Future<bool> getNotificationEnabled() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  return prefs.getBool('notification_enabled') ?? false;
}

// 切换通知逻辑
void toggleNotification(bool value, DateTime nextMarketDay) async {
  await saveNotificationEnabled(value);
  if (value) {
    bool granted = await requestNotificationPermission();
    if (granted) await scheduleMarketNotification(nextMarketDay);
  } else {
    await flutterLocalNotificationsPlugin.cancel(0); // 取消已设置的通知
  }
}

三、UI与逻辑结合

页面初始化时加载数据并更新UI:

@override
void initState() {
  super.initState();
  _initPageData();
}

Future<void> _initPageData() async {
  DateTime? baseDay = await getBaseMarketDay();
  if (baseDay == null) {
    // 无基准日时引导用户选择,或默认当前日期
    baseDay = DateTime.now();
    await saveBaseMarketDay(baseDay);
  }
  DateTime nextMarket = calculateNextMarketDay(baseDay, DateTime.now());
  bool notifyEnabled = await getNotificationEnabled();
  
  setState(() {
    _nextMarketDay = nextMarket;
    _notificationEnabled = notifyEnabled;
  });
}

最后在checkbox的onChanged回调中调用toggleNotification方法即可。


内容的提问来源于stack exchange,提问作者thebigbrownBox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:18:27