【问题标题】:How to achieve SingleLine Horizontal CalendarView in Flutter如何在 Flutter 中实现 SingleLine 水平 CalendarView
【发布时间】:2020-02-02 09:29:56
【问题描述】:

我是 Flutter 的新手。如何在颤动中实现SingleLine水平滚动CalendarView和日期选择。 请找到预期CalendarView 的下图。帮助将不胜感激

Expected CalendarView

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies flutter-animation


    【解决方案1】:

    你可以使用包https://pub.dev/packages/table_calendar
    在月份模式下,只会显示一行日期

    代码sn-p

    return TableCalendar(
          locale: 'pl_PL',
          calendarController: _calendarController,
          events: _events,
          holidays: _holidays,
          initialCalendarFormat: CalendarFormat.month,
          formatAnimation: FormatAnimation.slide,
          startingDayOfWeek: StartingDayOfWeek.sunday,
          availableGestures: AvailableGestures.all,
          availableCalendarFormats: const {
            CalendarFormat.month: '',
            CalendarFormat.week: '',
          },
    

    示例代码中,_buildButtons() 和 _buildEventList() 如果不需要,可以备注

    body: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              // Switch out 2 lines below to play with TableCalendar's settings
              //-----------------------
              _buildTableCalendar(),
              // _buildTableCalendarWithBuilders(),
              //const SizedBox(height: 8.0),
              //_buildButtons(),
              //const SizedBox(height: 8.0),
              //Expanded(child: _buildEventList()),
            ],
          ),
    

    完整示例代码

    //  Copyright (c) 2019 Aleksander Woźniak
    //  Licensed under Apache License v2.0
    
    import 'package:flutter/material.dart';
    import 'package:intl/date_symbol_data_local.dart';
    import 'package:table_calendar/table_calendar.dart';
    
    // Example holidays
    final Map<DateTime, List> _holidays = {
      DateTime(2019, 1, 1): ['New Year\'s Day'],
      DateTime(2019, 1, 6): ['Epiphany'],
      DateTime(2019, 2, 14): ['Valentine\'s Day'],
      DateTime(2019, 4, 21): ['Easter Sunday'],
      DateTime(2019, 4, 22): ['Easter Monday'],
    };
    
    void main() {
      initializeDateFormatting().then((_) => runApp(MyApp()));
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Table Calendar Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Table Calendar Demo'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      Map<DateTime, List> _events;
      List _selectedEvents;
      AnimationController _animationController;
      CalendarController _calendarController;
    
      @override
      void initState() {
        super.initState();
        final _selectedDay = DateTime.now();
    
        _events = {
          _selectedDay.subtract(Duration(days: 30)): ['Event A0', 'Event B0', 'Event C0'],
          _selectedDay.subtract(Duration(days: 27)): ['Event A1'],
          _selectedDay.subtract(Duration(days: 20)): ['Event A2', 'Event B2', 'Event C2', 'Event D2'],
          _selectedDay.subtract(Duration(days: 16)): ['Event A3', 'Event B3'],
          _selectedDay.subtract(Duration(days: 10)): ['Event A4', 'Event B4', 'Event C4'],
          _selectedDay.subtract(Duration(days: 4)): ['Event A5', 'Event B5', 'Event C5'],
          _selectedDay.subtract(Duration(days: 2)): ['Event A6', 'Event B6'],
          _selectedDay: ['Event A7', 'Event B7', 'Event C7', 'Event D7'],
          _selectedDay.add(Duration(days: 1)): ['Event A8', 'Event B8', 'Event C8', 'Event D8'],
          _selectedDay.add(Duration(days: 3)): Set.from(['Event A9', 'Event A9', 'Event B9']).toList(),
          _selectedDay.add(Duration(days: 7)): ['Event A10', 'Event B10', 'Event C10'],
          _selectedDay.add(Duration(days: 11)): ['Event A11', 'Event B11'],
          _selectedDay.add(Duration(days: 17)): ['Event A12', 'Event B12', 'Event C12', 'Event D12'],
          _selectedDay.add(Duration(days: 22)): ['Event A13', 'Event B13'],
          _selectedDay.add(Duration(days: 26)): ['Event A14', 'Event B14', 'Event C14'],
        };
    
        _selectedEvents = _events[_selectedDay] ?? [];
    
        _calendarController = CalendarController();
    
        _animationController = AnimationController(
          vsync: this,
          duration: const Duration(milliseconds: 400),
        );
    
        _animationController.forward();
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        _calendarController.dispose();
        super.dispose();
      }
    
      void _onDaySelected(DateTime day, List events) {
        print('CALLBACK: _onDaySelected');
        setState(() {
          _selectedEvents = events;
        });
      }
    
      void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
        print('CALLBACK: _onVisibleDaysChanged');
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              // Switch out 2 lines below to play with TableCalendar's settings
              //-----------------------
              _buildTableCalendar(),
              // _buildTableCalendarWithBuilders(),
              const SizedBox(height: 8.0),
              _buildButtons(),
              const SizedBox(height: 8.0),
              Expanded(child: _buildEventList()),
            ],
          ),
        );
      }
    
      // Simple TableCalendar configuration (using Styles)
      Widget _buildTableCalendar() {
        return TableCalendar(
          calendarController: _calendarController,
          events: _events,
          holidays: _holidays,
          startingDayOfWeek: StartingDayOfWeek.monday,
          calendarStyle: CalendarStyle(
            selectedColor: Colors.deepOrange[400],
            todayColor: Colors.deepOrange[200],
            markersColor: Colors.brown[700],
            outsideDaysVisible: false,
          ),
          headerStyle: HeaderStyle(
            formatButtonTextStyle: TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
            formatButtonDecoration: BoxDecoration(
              color: Colors.deepOrange[400],
              borderRadius: BorderRadius.circular(16.0),
            ),
          ),
          onDaySelected: _onDaySelected,
          onVisibleDaysChanged: _onVisibleDaysChanged,
        );
      }
    
      // More advanced TableCalendar configuration (using Builders & Styles)
      Widget _buildTableCalendarWithBuilders() {
        return TableCalendar(
          locale: 'pl_PL',
          calendarController: _calendarController,
          events: _events,
          holidays: _holidays,
          initialCalendarFormat: CalendarFormat.month,
          formatAnimation: FormatAnimation.slide,
          startingDayOfWeek: StartingDayOfWeek.sunday,
          availableGestures: AvailableGestures.all,
          availableCalendarFormats: const {
            CalendarFormat.month: '',
            CalendarFormat.week: '',
          },
          calendarStyle: CalendarStyle(
            outsideDaysVisible: false,
            weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
            holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
          ),
          daysOfWeekStyle: DaysOfWeekStyle(
            weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
          ),
          headerStyle: HeaderStyle(
            centerHeaderTitle: true,
            formatButtonVisible: false,
          ),
          builders: CalendarBuilders(
            selectedDayBuilder: (context, date, _) {
              return FadeTransition(
                opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
                child: Container(
                  margin: const EdgeInsets.all(4.0),
                  padding: const EdgeInsets.only(top: 5.0, left: 6.0),
                  color: Colors.deepOrange[300],
                  width: 100,
                  height: 100,
                  child: Text(
                    '${date.day}',
                    style: TextStyle().copyWith(fontSize: 16.0),
                  ),
                ),
              );
            },
            todayDayBuilder: (context, date, _) {
              return Container(
                margin: const EdgeInsets.all(4.0),
                padding: const EdgeInsets.only(top: 5.0, left: 6.0),
                color: Colors.amber[400],
                width: 100,
                height: 100,
                child: Text(
                  '${date.day}',
                  style: TextStyle().copyWith(fontSize: 16.0),
                ),
              );
            },
            markersBuilder: (context, date, events, holidays) {
              final children = <Widget>[];
    
              if (events.isNotEmpty) {
                children.add(
                  Positioned(
                    right: 1,
                    bottom: 1,
                    child: _buildEventsMarker(date, events),
                  ),
                );
              }
    
              if (holidays.isNotEmpty) {
                children.add(
                  Positioned(
                    right: -2,
                    top: -2,
                    child: _buildHolidaysMarker(),
                  ),
                );
              }
    
              return children;
            },
          ),
          onDaySelected: (date, events) {
            _onDaySelected(date, events);
            _animationController.forward(from: 0.0);
          },
          onVisibleDaysChanged: _onVisibleDaysChanged,
        );
      }
    
      Widget _buildEventsMarker(DateTime date, List events) {
        return AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          decoration: BoxDecoration(
            shape: BoxShape.rectangle,
            color: _calendarController.isSelected(date)
                ? Colors.brown[500]
                : _calendarController.isToday(date) ? Colors.brown[300] : Colors.blue[400],
          ),
          width: 16.0,
          height: 16.0,
          child: Center(
            child: Text(
              '${events.length}',
              style: TextStyle().copyWith(
                color: Colors.white,
                fontSize: 12.0,
              ),
            ),
          ),
        );
      }
    
      Widget _buildHolidaysMarker() {
        return Icon(
          Icons.add_box,
          size: 20.0,
          color: Colors.blueGrey[800],
        );
      }
    
      Widget _buildButtons() {
        return Column(
          children: <Widget>[
            Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                RaisedButton(
                  child: Text('month'),
                  onPressed: () {
                    setState(() {
                      _calendarController.setCalendarFormat(CalendarFormat.month);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('2 weeks'),
                  onPressed: () {
                    setState(() {
                      _calendarController.setCalendarFormat(CalendarFormat.twoWeeks);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('week'),
                  onPressed: () {
                    setState(() {
                      _calendarController.setCalendarFormat(CalendarFormat.week);
                    });
                  },
                ),
              ],
            ),
            const SizedBox(height: 8.0),
            RaisedButton(
              child: Text('setDay 10-07-2019'),
              onPressed: () {
                _calendarController.setSelectedDay(DateTime(2019, 7, 10), runCallback: true);
              },
            ),
          ],
        );
      }
    
      Widget _buildEventList() {
        return ListView(
          children: _selectedEvents
              .map((event) => Container(
                    decoration: BoxDecoration(
                      border: Border.all(width: 0.8),
                      borderRadius: BorderRadius.circular(12.0),
                    ),
                    margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
                    child: ListTile(
                      title: Text(event.toString()),
                      onTap: () => print('$event tapped!'),
                    ),
                  ))
              .toList(),
        );
      }
    }
    

    【讨论】:

    • 在这里,我只想显示 SigleLine 并且必须从 HeaderStyle 中删除(月、周和周)选项我只想只有月,帮帮我
    • 你的意思是availableCalendarFormats: const { CalendarFormat.month: '',你只需要月份吗?你可以直接删除周
    • 是的,我只需要一个月
    • initialCalendarFormat: CalendarFormat.week, availableCalendarFormats: const { CalendarFormat.week: 'Week', },
    • 将 initialCalendarFormat: 更改为 CalendarFormat.week 并添加 availableCalendarFormats ,就可以了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    相关资源
    最近更新 更多