add_calendar 0.0.1 copy "add_calendar: ^0.0.1" to clipboard
add_calendar: ^0.0.1 copied to clipboard

A Flutter plugin that invokes the native calendar app's "Add Event" page with prefilled fields, across Android, iOS, and HarmonyOS.

example/lib/main.dart

import 'package:add_calendar/add_calendar.dart';
import 'package:flutter/material.dart';
import 'dart:async';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _addCalendarPlugin = AddCalendarPlugin();

  final TextEditingController _titleController = TextEditingController(
    text: 'Flutter 插件示例日程',
  );
  final TextEditingController _notesController = TextEditingController(
    text: '这是一条由 plugindev 添加的测试日程',
  );
  final TextEditingController _reminderController = TextEditingController(
    text: '5,15,30',
  );

  bool _allDay = false;

  DateTime _startTime = DateTime.now().add(const Duration(hours: 1));
  DateTime _endTime = DateTime.now().add(const Duration(hours: 2));

  String _statusText = '';

  @override
  void dispose() {
    _titleController.dispose();
    _notesController.dispose();
    _reminderController.dispose();
    super.dispose();
  }

  Future<void> _pickStartTime() async {
    final picked = await _showDateTimePicker(_startTime);
    if (picked != null) {
      setState(() {
        _startTime = picked;
        if (!_endTime.isAfter(_startTime)) {
          _endTime = _startTime.add(const Duration(hours: 1));
        }
      });
    }
  }

  Future<void> _pickEndTime() async {
    final picked = await _showDateTimePicker(_endTime);
    if (picked != null) {
      setState(() {
        _endTime = picked;
      });
    }
  }

  Future<DateTime?> _showDateTimePicker(DateTime initial) async {
    final date = await showDatePicker(
      context: context,
      initialDate: initial,
      firstDate: DateTime(2000),
      lastDate: DateTime(2100),
    );
    if (date == null || !mounted) return null;
    final time = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.fromDateTime(initial),
    );
    if (time == null) return null;
    return DateTime(date.year, date.month, date.day, time.hour, time.minute);
  }

  Future<void> _requestPermission() async {
    final granted = await _addCalendarPlugin.requestPermission();
    setState(() {
      _statusText = granted ? '权限已授予' : '权限被拒绝';
    });
  }

  Future<void> _addEvent() async {
    if (_titleController.text.trim().isEmpty) {
      setState(() => _statusText = '标题不能为空');
      return;
    }

    final reminders = _reminderController.text
        .split(RegExp(r'[,,\s]+'))
        .where((s) => s.isNotEmpty)
        .map(int.tryParse)
        .whereType<int>()
        .where((n) => n > 0)
        .toList();

    final event = AddCalendarEvent(
      title: _titleController.text.trim(),
      startTimeMs: _startTime.millisecondsSinceEpoch,
      endTimeMs: _endTime.millisecondsSinceEpoch,
      allDay: _allDay,
      notes: _notesController.text.trim().isEmpty
          ? null
          : _notesController.text.trim(),
      minutesBeforeList: reminders.isEmpty ? null : reminders,
    );

    final saved = await _addCalendarPlugin.addEvent(event);
    setState(() => _statusText = saved ? '日程已添加' : '已取消或未保存');
  }

  String _formatDateTime(DateTime dt) {
    String two(int n) => n.toString().padLeft(2, '0');
    return '${dt.year}-${two(dt.month)}-${two(dt.day)} ${two(dt.hour)}:${two(dt.minute)}';
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: const Text('添加系统日历日程'),
        ),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ElevatedButton(
                onPressed: _requestPermission,
                child: const Text(
                  '申请日历权限',
                  style: TextStyle(color: Colors.black, fontSize: 16),
                ),
              ),
              const SizedBox(height: 24),
              const Text('标题', style: TextStyle(fontWeight: FontWeight.bold)),
              const SizedBox(height: 8),
              TextField(
                controller: _titleController,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: '请输入日程标题',
                ),
              ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text(
                          '开始时间',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(height: 8),
                        OutlinedButton(
                          onPressed: _pickStartTime,
                          child: Text(_formatDateTime(_startTime)),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text(
                          '结束时间',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(height: 8),
                        OutlinedButton(
                          onPressed: _pickEndTime,
                          child: Text(_formatDateTime(_endTime)),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              SwitchListTile(
                contentPadding: EdgeInsets.zero,
                title: const Text('全天事件'),
                value: _allDay,
                onChanged: (v) => setState(() => _allDay = v),
              ),
              const SizedBox(height: 8),
              const Text(
                '提醒(提前分钟数,逗号分隔)',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 8),
              TextField(
                controller: _reminderController,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: '例:5,15,30',
                ),
              ),
              const SizedBox(height: 16),
              const Text('备注', style: TextStyle(fontWeight: FontWeight.bold)),
              const SizedBox(height: 8),
              TextField(
                controller: _notesController,
                maxLines: 3,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: '请输入备注',
                ),
              ),
              const SizedBox(height: 24),
              ElevatedButton(
                onPressed: _addEvent,
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(vertical: 14),
                ),
                child: const Text(
                  '添加日程到系统日历',
                  style: TextStyle(color: Colors.black, fontSize: 16),
                ),
              ),
              const SizedBox(height: 24),
              if (_statusText.isNotEmpty)
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: Colors.grey.shade100,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Text(_statusText),
                ),
              const SizedBox(height: 40),
            ],
          ),
        ),
      ),
    );
  }
}
1
likes
130
points
90
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin that invokes the native calendar app's "Add Event" page with prefilled fields, across Android, iOS, and HarmonyOS.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on add_calendar

Packages that implement add_calendar