Last active
December 16, 2022 08:34
-
-
Save shakir915/d2c4226182c27df4aa380c2e15e23304 to your computer and use it in GitHub Desktop.
Calendar Widget flutter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:intl/intl.dart'; | |
class CalendarWidget extends StatefulWidget { | |
final Function(DateTime dateTime) onDateSelect; | |
CalendarWidget(this.onDateSelect, {Key? key}) : super(key: key); | |
@override | |
State<CalendarWidget> createState() => _CalendarWidgetState(); | |
} | |
class _CalendarWidgetState extends State<CalendarWidget> { | |
List<List<DateData>> listLists = List.empty(growable: true); | |
var cellWidth = 47.0; | |
var cellHeight = 38.0; | |
var selectedEpochMilli = 0; | |
var showingMonthEpochMilli = 0; | |
@override | |
void initState() { | |
listLists.clear(); | |
var now = DateTime.now(); | |
selectedEpochMilli = now.millisecondsSinceEpoch; | |
widget.onDateSelect(now); | |
showingMonthEpochMilli = selectedEpochMilli; | |
listLists.addAll(getDates(showingMonthEpochMilli).chunked(7)); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Column( | |
children: [ | |
Container(height: 44), | |
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ | |
InkWell( | |
splashFactory: NoSplash.splashFactory, | |
child: Padding( | |
padding: const EdgeInsets.only( | |
left: 15.0, right: 8.0, top: 8.0, bottom: 8.0), | |
child: Icon( | |
Icons.keyboard_arrow_left_outlined, | |
size: 30, | |
), | |
), | |
onTap: () { | |
clickNextPrevMonth(-1); | |
}, | |
), | |
Text( | |
DateFormat("MMMM - yyyy").format( | |
DateTime.fromMillisecondsSinceEpoch(showingMonthEpochMilli)), | |
style: TextStyle( | |
color: Color( | |
0xffDA137C, | |
), | |
fontSize: 18 ), | |
), | |
InkWell( | |
splashFactory: NoSplash.splashFactory, | |
child: Padding( | |
padding: const EdgeInsets.only( | |
left: 8.0, right: 25.0, top: 8.0, bottom: 8.0), | |
child: Icon( | |
Icons.keyboard_arrow_right_outlined, | |
size: 30, | |
), | |
), | |
onTap: () { | |
clickNextPrevMonth(1); | |
}, | |
), | |
]), | |
Container(height: 14), | |
Padding( | |
padding: const EdgeInsets.only(left: 5, right: 13), | |
child: Container( | |
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0), | |
decoration: BoxDecoration( | |
color: Color(0xFFF4F4F4), | |
borderRadius: BorderRadius.all(Radius.circular(23 )), | |
), | |
child: Row( | |
children: ["S", "S", "M", "T", "W", "T", "F"] | |
.map((i) => Container( | |
height: cellHeight, | |
width: cellWidth, | |
child: Center( | |
child: Text( | |
i, | |
style: TextStyle( | |
color: Color( | |
0xff67646D, | |
), | |
fontSize: 16), | |
), | |
), | |
)) | |
.toList()), | |
), | |
), | |
Padding( | |
padding: | |
const EdgeInsets.only(left: 10, right: 0, bottom: 0, top: 10), | |
child: Column( | |
children: listLists | |
.map((list) => Row( | |
children: list.map((data) { | |
var color = Color( | |
0xfff67646D, | |
); | |
var bgColor = Colors.transparent; | |
if (data.epochMilli == selectedEpochMilli) { | |
color = Colors.white; | |
bgColor = Color( | |
0xFFDA137C, | |
); | |
} | |
if (data.isCurrentMonth != 0) { | |
color = Color( | |
0xffB7B7B7, | |
); | |
bgColor = Colors.transparent; | |
} | |
return InkWell( | |
splashFactory: NoSplash.splashFactory, | |
onTap: () { | |
if (data.isCurrentMonth == 0) | |
setState(() { | |
selectedEpochMilli = data.epochMilli; | |
widget.onDateSelect(DateTime.fromMillisecondsSinceEpoch(selectedEpochMilli)); | |
}); | |
}, | |
child: Container( | |
height: cellHeight, | |
width: cellWidth, | |
child: Padding( | |
padding: const EdgeInsets.all(4.0), | |
child: Container( | |
decoration: BoxDecoration( | |
color: bgColor, | |
shape: BoxShape.circle, | |
), | |
child: Center( | |
child: Text( | |
data.date.toString(), | |
style: TextStyle( | |
color: color, | |
fontSize: 16), | |
textAlign: TextAlign.center, | |
), | |
), | |
), | |
), | |
), | |
); | |
}).toList())) | |
.toList(), | |
), | |
) | |
], | |
); | |
; | |
} | |
void clickNextPrevMonth(int i) { | |
var dt = DateTime.fromMillisecondsSinceEpoch(showingMonthEpochMilli); | |
dt = DateTime(dt.year, dt.month + i, dt.day, dt.hour, dt.minute, dt.second, | |
dt.millisecond, dt.microsecond); | |
showingMonthEpochMilli = dt.millisecondsSinceEpoch; | |
listLists.clear(); | |
listLists.addAll(getDates(showingMonthEpochMilli).chunked(7)); | |
setState(() {}); | |
} | |
List<DateData> getDates(int showingMonthEpochMilli) { | |
List<DateData> list = List.empty(growable: true); | |
var iDate = DateTime.fromMillisecondsSinceEpoch(showingMonthEpochMilli); | |
var showMonth = iDate.month; | |
iDate = DateTime(iDate.year, iDate.month, 1, iDate.hour, iDate.minute, | |
iDate.second, iDate.millisecond, iDate.microsecond); | |
while (iDate.month == showMonth) { | |
list.add(DateData(iDate.day, iDate.millisecondsSinceEpoch, 0)); | |
iDate = iDate.add(Duration(days: 1)); | |
} | |
while (iDate.weekday != DateTime.saturday) { | |
list.add(DateData(iDate.day, iDate.millisecondsSinceEpoch, 1)); | |
iDate = iDate.add(Duration(days: 1)); | |
} | |
iDate = DateTime(iDate.year, iDate.month - 1, 1, iDate.hour, iDate.minute, | |
iDate.second, iDate.millisecond, iDate.microsecond); | |
iDate = iDate.subtract(Duration(days: 1)); | |
while (iDate.weekday != DateTime.friday) { | |
list.insert(0, DateData(iDate.day, iDate.millisecondsSinceEpoch, -1)); | |
iDate = iDate.subtract(Duration(days: 1)); | |
} | |
return list; | |
} | |
} | |
class DateData { | |
final int date; | |
final int epochMilli; | |
final int isCurrentMonth; | |
DateData(this.date, this.epochMilli, this.isCurrentMonth); | |
/// 0 for current month //1 for next // -1 for prev | |
} | |
extension IterableExtensions<E> on Iterable<E> { | |
Iterable<List<E>> chunked(int chunkSize) sync* { | |
if (length <= 0) { | |
yield []; | |
return; | |
} | |
int skip = 0; | |
while (skip < length) { | |
final chunk = this.skip(skip).take(chunkSize); | |
yield chunk.toList(growable: false); | |
skip += chunkSize; | |
if (chunk.length < chunkSize) return; | |
} | |
} | |
} |
Author
shakir915
commented
Dec 16, 2022
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment