动态自定义日历

时间:2020-09-21 05:51:50

标签: flutter

我想按周显示图像中显示的日历。显示从星期日到星期六的星期几并显示日期。左键单击显示上周日期,右键单击显示下周日期。我还需要获取星期的开始日期和结束日期。

我尝试在flutter中使用一些插件,但是我没有得到想要的东西,所以现在我想在flutter中创建动态自定义日历。

enter image description here

1 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
以下是对软件包https://pub.dev/packages/g2x_week_calendar的修改
您可以从MyDateTime.getFirstDateOfWeek开始一周 代码段

class MyDateTime {
  static String formatDate(DateTime date, {String format = "dd/MM/yyyy"}) {
    var str = format.replaceAll(
        "dd", (date.day < 10 ? "0" : "") + date.day.toString());
    str = str.replaceAll(
        "MM", (date.month < 10 ? "0" : "") + date.month.toString());
    str = str.replaceAll("yyyy", date.year.toString());
    return str;
  }

  ///get first date of week
  static DateTime getFirstDateOfWeek(DateTime date) {
    return date.weekday == 7 ? date : date.add(Duration(days: -date.weekday));
  }
... 
G2xSimpleWeekCalendar(
      100.0,
      DateTime.now(),
      dateCallback: (date) => _dateCallback(date),
      typeCollapse: true,
      //backgroundDecoration: BoxDecoration(color: Colors.blue),
    ),

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

class MyDateTime {
  static String formatDate(DateTime date, {String format = "dd/MM/yyyy"}) {
    var str = format.replaceAll(
        "dd", (date.day < 10 ? "0" : "") + date.day.toString());
    str = str.replaceAll(
        "MM", (date.month < 10 ? "0" : "") + date.month.toString());
    str = str.replaceAll("yyyy", date.year.toString());
    return str;
  }

  ///get first date of week
  static DateTime getFirstDateOfWeek(DateTime date) {
    return date.weekday == 7 ? date : date.add(Duration(days: -date.weekday));
  }

  ///get all days of week
  static List<int> getDaysOfWeek(DateTime date) {
    var firstDay = getFirstDateOfWeek(date);
    var days = <int>[];
    for (var i = 0; i < 7; i++) {
      days.add(firstDay.add(Duration(days: i)).day);
    }
    return days;
  }
}

typedef void DateCallback(DateTime val);

class G2xSimpleWeekCalendar extends StatefulWidget {
  G2xSimpleWeekCalendar(
    this.bodyHeight,
    this.currentDate, {
    this.strWeekDays = const [
      "Sun",
      "Mon",
      "Tues",
      "Wed",
      "Thurs",
      "Fri",
      "Sat"
    ],
    this.format = "yyyy/MM/dd",
    this.dateCallback,
    this.defaultTextStyle = const TextStyle(),
    this.selectedTextStyle = const TextStyle(color: Colors.red),
    this.selectedBackgroundDecoration = const BoxDecoration(),
    this.backgroundDecoration = const BoxDecoration(),
    this.typeCollapse = false,
  });
  final DateTime currentDate;
  final List<String> strWeekDays;
  final String format;
  final DateCallback dateCallback;
  //style
  final TextStyle defaultTextStyle;
  final TextStyle selectedTextStyle;
  final BoxDecoration selectedBackgroundDecoration;
  final BoxDecoration backgroundDecoration;
  final bool typeCollapse;
  final double bodyHeight;
  @override
  _G2xSimpleWeekCalendarState createState() => _G2xSimpleWeekCalendarState();
}

class _G2xSimpleWeekCalendarState extends State<G2xSimpleWeekCalendar>
    with TickerProviderStateMixin {
  DateTime currentDate;
  var weekDays = <int>[];
  var selectedIndex = 0;
  var _close = false;

  //Collapse
  AnimationController _collapseController;
  Animation<double> _collpseAnimation;
  var _heightCollapse = 0.0;

  _setSelectedDate(int index) {
    setState(() {
      selectedIndex = index;
      currentDate =
          MyDateTime.getFirstDateOfWeek(currentDate).add(Duration(days: index));
      if (widget.dateCallback != null) widget.dateCallback(currentDate);
    });
  }

  _altertWeek(int days) {
    setState(() {
      currentDate = currentDate.add(Duration(days: days));
      if (widget.dateCallback != null) widget.dateCallback(currentDate);
    });
  }

  _collapse() {
    if (!widget.typeCollapse) return;
    if (_collapseController.status == AnimationStatus.completed && _close) {
      _collapseController.reverse();
      _close = false;
    } else if (_collapseController.status == AnimationStatus.dismissed) {
      _collapseController.forward();
      _close = true;
    }
  }

  @override
  void initState() {
    super.initState();
    currentDate = widget.currentDate;
    // if(widget.dateCallback != null)
    //   widget.dateCallback(currentDate);
    selectedIndex = currentDate.weekday == 7 ? 0 : currentDate.weekday;

    //Collapse
    _heightCollapse = widget.bodyHeight;
    _collapseController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    _collpseAnimation = Tween<double>(begin: widget.bodyHeight, end: 0)
        .animate(_collapseController);
    _collapseController.addListener(() {
      setState(() {
        _heightCollapse = _collpseAnimation.value;
      });
      if (_collapseController.status == AnimationStatus.completed && !_close) {
        _collapseController.reset();
        _close = false;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    weekDays = MyDateTime.getDaysOfWeek(currentDate);
    var size = MediaQuery.of(context).size;
    var sizePart = size.width / 4 - 10;
    var rowWeeks = Column(
      children: <Widget>[
        Container(
            decoration: widget.backgroundDecoration,
            padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 5),
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Container(
                      width: sizePart * 2,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Text(
                              MyDateTime.formatDate(currentDate,
                                  format: widget.format),
                              style: widget.defaultTextStyle),
                        ],
                      )),
                ])),
        Container(
            //height: _heightCollapse,
            decoration: widget.backgroundDecoration,
            padding: EdgeInsets.only(bottom: 5, left: 5, right: 5),
            child: Row(
              children: [
                InkWell(
                  onTap: () => _altertWeek(-7),
                  child: Icon(Icons.arrow_left,
                      color: widget.defaultTextStyle.color),
                ),
                Expanded(
                  child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: widget.strWeekDays.map((i) {
                        return InkWell(
                            onTap: () =>
                                _setSelectedDate(widget.strWeekDays.indexOf(i)),
                            child: Container(
                              padding: EdgeInsets.all(5),
                              decoration:
                                  selectedIndex == widget.strWeekDays.indexOf(i)
                                      ? widget.selectedBackgroundDecoration
                                      : BoxDecoration(),
                              child: Column(
                                children: <Widget>[
                                  Text(i,
                                      style: selectedIndex ==
                                              widget.strWeekDays.indexOf(i)
                                          ? widget.selectedTextStyle
                                          : widget.defaultTextStyle),
                                  SizedBox(
                                    height: 2,
                                  ),
                                  selectedIndex == widget.strWeekDays.indexOf(i)
                                      ? CircleAvatar(
                                          backgroundColor: Colors.orange,
                                          child: Text(
                                              weekDays[widget.strWeekDays
                                                      .indexOf(i)]
                                                  .toString(),
                                              style: selectedIndex ==
                                                      widget.strWeekDays
                                                          .indexOf(i)
                                                  ? widget.selectedTextStyle
                                                  : widget.defaultTextStyle))
                                      : Text(
                                          weekDays[
                                                  widget.strWeekDays.indexOf(i)]
                                              .toString(),
                                          style: selectedIndex ==
                                                  widget.strWeekDays.indexOf(i)
                                              ? widget.selectedTextStyle
                                              : widget.defaultTextStyle),
                                ],
                              ),
                            ));
                      }).toList()),
                ),
                InkWell(
                  onTap: () => _altertWeek(7),
                  child: Icon(Icons.arrow_right,
                      color: widget.defaultTextStyle.color),
                )
              ],
            ))
      ],
    );
    return rowWeeks;
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  DateTime dateCallback;

  _dateCallback(DateTime date) {
    dateCallback = date;
    print(dateCallback);
  }

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            G2xSimpleWeekCalendar(
              100.0,
              DateTime.now(),
              dateCallback: (date) => _dateCallback(date),
              typeCollapse: true,
              //backgroundDecoration: BoxDecoration(color: Colors.blue),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}