Skip to content

Instantly share code, notes, and snippets.

@chaudharydeepanshu
Created August 7, 2022 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chaudharydeepanshu/edebcf0d21877739e62efc420cd154db to your computer and use it in GitHub Desktop.
Save chaudharydeepanshu/edebcf0d21877739e62efc420cd154db to your computer and use it in GitHub Desktop.
pskink gist for calendar
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: const Home(),
);
}
}
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(body: PagedCalendar());
}
}
class PagedCalendar extends StatefulWidget {
@override
State<PagedCalendar> createState() => _PagedCalendarState();
}
class _PagedCalendarState extends State<PagedCalendar> {
late Map<int, Widget> _days;
int month = 1;
@override
void initState() {
super.initState();
const padding = EdgeInsets.all(2);
final style = ButtonStyle(
foregroundColor: MaterialStateProperty.all(Colors.black87),
textStyle: MaterialStateProperty.all(
const TextStyle(fontWeight: FontWeight.bold)),
side: MaterialStateProperty.all(
const BorderSide(width: 3, color: Colors.black45)),
padding: MaterialStateProperty.all(EdgeInsets.zero),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12))),
);
final disabledStyle = ButtonStyle(
foregroundColor: MaterialStateProperty.all(Colors.black45),
textStyle: MaterialStateProperty.all(
const TextStyle(fontWeight: FontWeight.normal)),
side: MaterialStateProperty.all(
const BorderSide(width: 2, color: Colors.black12)),
padding: MaterialStateProperty.all(EdgeInsets.zero),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12))),
);
_days = {
for (int i = 1; i <= 31; i++) // current month
i: OutlinedButton(
onPressed: () => _onPressed(i),
style: style,
child: Text(i.toString())),
for (int i = 1; i <= 31; i++) // other month
100 + i: OutlinedButton(
onPressed: null, style: disabledStyle, child: Text(i.toString())),
};
_days.forEach(
(key, child) => _days[key] = Padding(padding: padding, child: child));
}
_onPressed(int day) {
print('day: $day, month: $month');
}
@override
Widget build(BuildContext context) {
return PageView.builder(
itemCount: 12,
itemBuilder: (ctx, i) {
const materialLocalizations = DefaultMaterialLocalizations();
final year = DateTime.now().year;
month = i + 1;
final m = Month(
name: materialLocalizations.formatMonthYear(DateTime(year, month)),
length: DateUtils.getDaysInMonth(year, month),
prevMonthLength: month == 1
? DateUtils.getDaysInMonth(year - 1, 12)
: DateUtils.getDaysInMonth(year, month - 1),
firstDayInWeek:
DateUtils.firstDayOffset(year, month, materialLocalizations),
);
return Column(
children: [
Text(m.name, style: Theme.of(context).textTheme.headline5),
Expanded(
child: GridView.count(
crossAxisCount: 7,
children: [...fillGrid(m).map((key) => _days[key]!)],
),
),
],
);
});
}
Iterable<int> fillGrid(Month month) sync* {
// prev month
final idx = month.prevMonthLength - month.firstDayInWeek + 101;
yield* Iterable.generate(month.firstDayInWeek, (i) => i + idx);
// current month
yield* Iterable.generate(month.length, (i) => i + 1);
// next month
final fillEnd = (month.firstDayInWeek + month.length) % 7;
if (fillEnd > 0) {
int day = 101;
yield* Iterable.generate(7 - fillEnd, (i) => day++);
}
}
}
class Month {
Month(
{required this.name,
required this.length,
required this.prevMonthLength,
required this.firstDayInWeek});
final String name;
final int length;
final int prevMonthLength;
final int firstDayInWeek;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment