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

Android Studio环境下使用Flutter实现日历Widget的方法与示例

enter image description here

实现方案

Flutter完全可以实现安卓主屏幕日历Widget,目前生态已经有成熟的落地路径,不需要从零手写平台层逻辑,下面是可直接复用的实现参考:
目前主流实现分两类:

  • 快速实现:使用home_widget插件,封装了Flutter和原生Widget的通信、渲染逻辑,90%以上的日历场景都能用这个方案搞定,稳定性足够
  • 自定义实现:手写MethodChannel对接安卓原生AppWidget框架,灵活度最高,适合需要复杂交互、动画的特殊场景,但是适配成本高

基于home_widget的日历Widget实现步骤

1. 配置依赖

在项目的pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  home_widget: ^0.6.0 # 可以替换为pub上的最新稳定版本

2. 安卓端原生配置

首先在android/app/src/main/AndroidManifest.xml的<application>标签内注册Widget接收器:

<receiver android:name="io.flutter.plugins.homewidget.HomeWidgetReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/widget_info" />
</receiver>

接着在android/app/src/main/res下新建xml目录,创建widget_info.xml配置Widget的基础属性:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dp"
    android:minHeight="180dp"
    android:updatePeriodMillis="1800000"
    android:initialLayout="@layout/widget_initial"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen">
</appwidget-provider>

注意安卓系统对Widget的后台自动更新有强制限制,最短间隔为30分钟,日历类场景不需要依赖这个自动更新,在App内添加/修改日程、切换日期时主动触发刷新即可。

然后在res/layout目录下新建widget_initial.xml作为Widget加载前的占位布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="12dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="日历加载中..." />
</FrameLayout>

3. Flutter层代码实现

核心逻辑是把Flutter写的日历组件渲染为位图,同步给原生层展示,示例代码如下:

import 'package:flutter/material.dart';
import 'package:home_widget/home_widget.dart';

// 和Manifest中注册的接收器类名保持一致
const String _widgetProviderName = 'HomeWidgetReceiver';
const String _widgetRenderKey = 'calendar_widget_view';

class CalendarHomePage extends StatefulWidget {
  const CalendarHomePage({super.key});

  @override
  State<CalendarHomePage> createState() => _CalendarHomePageState();
}

class _CalendarHomePageState extends State<CalendarHomePage> {
  @override
  void initState() {
    super.initState();
    // App启动时主动刷新一次桌面Widget
    refreshDesktopCalendar();
  }

  Future<void> refreshDesktopCalendar() async {
    // 这里写你的日历组件,和普通Flutter页面写法完全一致,可以加月视图、日期标记、日程红点等逻辑
    final calendarView = RepaintBoundary(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16),
        ),
        padding: const EdgeInsets.all(16),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              '2024年6月',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
            ),
            const SizedBox(height: 12),
            // 省略日历日期网格、日程标记的具体实现,按普通Flutter组件写即可
          ],
        ),
      ),
    );

    // 将Flutter组件渲染为位图同步给原生
    await HomeWidget.renderFlutterWidget(
      calendarView,
      key: _widgetRenderKey,
      logicalSize: const Size(300, 220), // 匹配你配置的Widget实际显示尺寸
    );
    // 通知系统刷新桌面Widget
    await HomeWidget.updateWidget(androidName: _widgetProviderName);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('日历设置')),
      body: Center(
        child: ElevatedButton(
          // 比如修改日程后手动调用刷新方法即可更新桌面Widget
          onPressed: refreshDesktopCalendar,
          child: const Text('同步日历到桌面'),
        ),
      ),
    );
  }
}

如果需要实现点击Widget上的日期跳转到App对应日程页的交互,直接用home_widget封装的点击跳转接口即可,不需要额外写原生代码。
如果你的日历Widget需要支持滑动、实时动画这类动态效果,位图渲染方案性能不够,再考虑手写MethodChannel嵌入Flutter引擎的方案,普通静态展示+点击交互的日历场景,上面的方案已经足够稳定,线上很多Flutter做的日历Widget都是用这个逻辑实现的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:21:26