Flutter周视图日历插件weekview_calendar的使用

Flutter周视图日历插件weekview_calendar的使用

特性

自定义化且功能丰富的Flutter周视图日历组件。

  • 强大易用的API
  • 预配置的UI并支持自定义样式
  • 自定义选择构建器以实现无限UI设计
  • 支持多语言
  • 支持日期范围选择
  • 支持月份和年份选择
  • 多日期选择支持
  • 动态事件和假期
  • 垂直自动调整大小 - 适应内容或填充视口
  • 多种日历格式(月、两周、周)
  • 水平滑动边界(首日、最后一天)

安装

pubspec.yaml文件中添加以下依赖:

dependencies:
  weekview_calendar: ^0.0.8

基本设置

WeekviewCalendar组件需要你提供firstDaylastDayfocusedDay参数:

  • firstDay 是日历的第一个可用日期。用户无法访问该日期之前的日子。
  • lastDay 是日历的最后一个可用日期。用户无法访问该日期之后的日子。
  • focusedDay 是当前目标日期。使用此属性来确定当前应显示哪个月。

示例代码:

WeekviewCalendar(
  firstDay: DateTime.utc(2010, 10, 16),
  lastDay: DateTime.utc(2030, 3, 14),
  focusedDay: DateTime.now(),
);

添加交互性

你会注意到先前设置的日历组件并不具备交互性 - 你只能通过水平滑动来改变当前可见的月份。虽然这在某些情况下可能足够,但你可以通过指定一些回调轻松地使它变得更具交互性。

示例代码:

selectedDayPredicate: (day) {
  return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
  setState(() {
    _selectedDay = selectedDay;
    _focusedDay = focusedDay; // 更新 `_focusedDay`
  });
},

为了动态更新可见的日历格式,可以添加以下代码:

calendarFormat: _calendarFormat,
onFormatChanged: (format) {
  setState(() {
    _calendarFormat = format;
  });
},

这两个更改将使日历具有交互性,并响应用户的输入。

更新focusedDay

focusedDay设置为静态值意味着每次WeekviewCalendar组件重建时,都会使用该特定的focusedDay。你可以通过热重载快速测试这一点:将focusedDay设置为DateTime.now(),滑动到下一个月并触发热重载 - 日历会“重置”到初始状态。为了避免这种情况发生,你应该在任何回调暴露focusedDay时存储并更新它。

示例代码:

onPageChanged: (focusedDay) {
  _focusedDay = focusedDay;
},

需要注意的是,在onPageChanged()回调内部不需要调用setState()。你只需更新存储的值,以便如果组件稍后被重建,它将使用正确的focusedDay

事件

你可以向WeekviewCalendar组件提供自定义事件。为此,使用eventLoader属性 - 你将获得一个DateTime对象,并为其分配一个事件列表。

示例代码:

eventLoader: (day) {
  return _getEventsForDay(day);
},

_getEventsForDay()可以是任何实现。例如,可以使用Map<DateTime, List<T>>

List<Event> _getEventsForDay(DateTime day) {
  return events[day] ?? [];
}

值得注意的是,DateTime对象包含日期和时间部分。在许多情况下,这个时间部分对于日历相关方面是多余的。

如果你决定使用Map,建议将其更改为LinkedHashMap - 这将允许你覆盖两个DateTime对象的相等比较,仅根据它们的日期部分进行比较:

final events = LinkedHashMap(
  equals: isSameDay,
  hashCode: getHashCode,
)..addAll(eventSource);

周期性事件

eventLoader允许你轻松添加重复的事件。例如,这将在每个星期一添加一个事件:

eventLoader: (day) {
  if (day.weekday == DateTime.monday) {
    return [Event('周期性事件')];
  }

  return [];
},

点击选中事件

通常情况下,希望有一个子列表,其中包含点击某天后选中的事件。你可以通过在eventLoader中使用的相同方法来实现这一点,即在onDaySelected回调中使用:

void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
  if (!isSameDay(_selectedDay, selectedDay)) {
    setState(() {
      _focusedDay = focusedDay;
      _selectedDay = selectedDay;
      _selectedEvents = _getEventsForDay(selectedDay);
    });
  }
}

自定义UI与CalendarBuilders

你可以从任何构建器返回null以使用默认样式。例如,以下代码片段仅覆盖周日的星期几标签(Sun),其他星期几标签保持不变:

calendarBuilders: CalendarBuilders(
  dowBuilder: (context, day) {
    if (day.weekday == DateTime.sunday) {
      final text = DateFormat.E().format(day);

      return Center(
        child: Text(
          text,
          style: TextStyle(color: Colors.red),
        ),
      );
    }
  },
),

本地化

要将日历显示为所需的语言,请使用locale属性。如果不指定,则使用默认语言。

初始化

在使用本地化之前,你可能需要初始化日期格式。

简单的方法如下:

  1. 首先,在pubspec.yaml文件中添加intl包。
  2. 然后,修改你的main()函数:
import 'package:intl/date_symbol_data_local.dart';

void main() {
  initializeDateFormatting().then((_) => runApp(MyApp()));
}

完成以上两步后,你的应用应该能够使用不同的语言显示WeekviewCalendar

指定语言

要指定一种语言,只需将其作为字符串代码传递给locale属性。

例如,这将使WeekviewCalendar使用波兰语:

WeekviewCalendar(
  locale: 'pl_PL',
),

注意,如果你想更改FormatButton文本的语言,必须自己处理。使用availableCalendarFormats属性,并在那里传递翻译后的字符串。使用你喜欢的国际化方法。

你也可以通过将formatButtonVisible设置为false来隐藏按钮。

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';

import 'pages/basics_example.dart';
import 'pages/complex_example.dart';
import 'pages/events_example.dart';
import 'pages/multi_example.dart';
import 'pages/range_example.dart';

void main() {
  initializeDateFormatting().then((_) => runApp(MyApp()));
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WeekView Calendar Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: StartPage(),
    );
  }
}

class StartPage extends StatefulWidget {
  [@override](/user/override)
  _StartPageState createState() => _StartPageState();
}

class _StartPageState extends State<StartPage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WeekView Calendar Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const SizedBox(height: 20.0),
            ElevatedButton(
              child: Text('基础示例'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => WeekViewBasicsExample()),
              ),
            ),
            const SizedBox(height: 12.0),
            ElevatedButton(
              child: Text('范围选择'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => WeekViewRangeExample()),
              ),
            ),
            const SizedBox(height: 12.0),
            ElevatedButton(
              child: Text('事件'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => WeekViewEventsExample()),
              ),
            ),
            const SizedBox(height: 12.0),
            ElevatedButton(
              child: Text('多选'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => WeekViewMultiExample()),
              ),
            ),
            const SizedBox(height: 12.0),
            ElevatedButton(
              child: Text('复杂示例'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => WeekViewComplexExample()),
              ),
            ),
            const SizedBox(height: 20.0),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter周视图日历插件weekview_calendar的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter周视图日历插件weekview_calendar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用weekview_calendar插件的一个简单示例。这个插件允许你创建一个周视图日历,用户可以在其中查看和选择日期。

首先,你需要在你的pubspec.yaml文件中添加weekview_calendar依赖:

dependencies:
  flutter:
    sdk: flutter
  weekview_calendar: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter项目中创建一个周视图日历。以下是一个完整的示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WeekView Calendar Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: WeekViewCalendarExample(),
    );
  }
}

class WeekViewCalendarExample extends StatefulWidget {
  @override
  _WeekViewCalendarExampleState createState() => _WeekViewCalendarExampleState();
}

class _WeekViewCalendarExampleState extends State<WeekViewCalendarExample> {
  final List<DateTime> _events = [
    DateTime(2023, 10, 5), // 示例事件
    DateTime(2023, 10, 7), // 示例事件
  ];

  final Map<DateTime, String> _eventDetails = {
    DateTime(2023, 10, 5): 'Event 1',
    DateTime(2023, 10, 7): 'Event 2',
  };

  DateTime _selectedDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WeekView Calendar Example'),
      ),
      body: WeekViewCalendar(
        initialDate: DateTime.now(),
        firstDayOfWeek: DayOfWeek.monday,
        eventColors: [Colors.blue, Colors.red], // 根据事件数量提供颜色
        events: _events,
        onEventSelected: (event) {
          // 当事件被点击时触发
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text('Selected: ${_eventDetails[event]}'),
            ),
          );
        },
        onDateSelected: (date) {
          // 当日期被点击时触发
          setState(() {
            _selectedDate = date;
          });
        },
        currentDate: _selectedDate,
        onCurrentDateChanged: (date) {
          // 当当前日期变更时触发
          setState(() {
            _selectedDate = date;
          });
        },
      ),
    );
  }
}

在这个示例中,我们:

  1. 创建了一个WeekViewCalendarExample组件,它包含了周视图日历的逻辑。
  2. 定义了两个列表:_events(包含事件的日期)和_eventDetails(包含事件的详细信息)。
  3. 使用WeekViewCalendar组件,并设置了初始日期、每周的第一天、事件颜色、事件列表、以及几个回调函数(onEventSelectedonDateSelectedonCurrentDateChanged)。

这个示例展示了如何集成weekview_calendar插件,并处理事件的点击和日期的选择。你可以根据自己的需求进一步自定义和扩展这个示例。

回到顶部