No Description

calendario.dart 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import 'package:flutter/material.dart';
  2. import 'package:intl/date_symbol_data_local.dart';
  3. import 'package:table_calendar/table_calendar.dart';
  4. // Dias de Citas No Disponibles
  5. final Map<DateTime, List> _holidays = {
  6. DateTime(2020, 11, 6): ['No Hay Citas'],
  7. DateTime(2020, 11, 3): ['Dia Elecciones'],
  8. DateTime(2020,12,25): ['Chrismas'],
  9. DateTime(2020,12,31): ['Despedida del anyo nuevo'],
  10. };
  11. //Iniciar la Seccion de las Citas
  12. void main() {
  13. initializeDateFormatting().then((_) => runApp(Calendario()));
  14. }
  15. //Inicio del Area de las Citas Disponibles
  16. class Calendario extends StatelessWidget {
  17. @override
  18. Widget build(BuildContext context) {
  19. return MaterialApp(
  20. title: 'Citas Disponibles',
  21. theme: ThemeData(
  22. primarySwatch: Colors.blue,
  23. ),
  24. home: MyHomePage(title: 'Citas Disponibles'),
  25. );
  26. }
  27. }
  28. class MyHomePage extends StatefulWidget {
  29. MyHomePage({Key key, this.title}) : super(key: key);
  30. final String title;
  31. @override
  32. _MyHomePageState createState() => _MyHomePageState();
  33. }
  34. //Definimos los controladores del Calendario
  35. class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  36. Map<DateTime, List> _events;
  37. List _selectedEvents;
  38. AnimationController _animationController;
  39. CalendarController _calendarController;
  40. Map<DateTime,List<dynamic>> _events2;
  41. //Definimos el dia elegido
  42. @override
  43. void initState() {
  44. super.initState();
  45. final _selectedDay = DateTime.now();
  46. _events = {
  47. //Ejemplos de Citas Previamente Hechas de Prueba Para los Recordatorios
  48. _selectedDay.add(Duration(days: 3)): Set.from([ 'Cita Cardiologo', 'Cita Dentista']).toList(),
  49. _selectedDay.add(Duration(days: 22)): ['Cita Cardiologo', 'Cita Dentista'],
  50. };
  51. //Dias de Citas Seleccionados como Recordatorio
  52. _selectedEvents = _events[_selectedDay] ?? [];
  53. _calendarController = CalendarController();
  54. _events2 = {};
  55. _animationController = AnimationController(
  56. vsync: this,
  57. duration: const Duration(milliseconds: 400),
  58. );
  59. _animationController.forward();
  60. }
  61. Map<String,dynamic> encodeMap(Map<DateTime,dynamic> map) {
  62. Map<String,dynamic> newMap = {};
  63. map.forEach((key,value) {
  64. newMap[key.toString()] = map[key];
  65. });
  66. return newMap;
  67. }
  68. Map<DateTime,dynamic> decodeMap(Map<String,dynamic> map) {
  69. Map<DateTime,dynamic> newMap = {};
  70. map.forEach((key,value) {
  71. newMap[DateTime.parse(key)] = map[key];
  72. });
  73. return newMap;
  74. }
  75. @override
  76. void dispose() {
  77. _animationController.dispose();
  78. _calendarController.dispose();
  79. super.dispose();
  80. }
  81. //Acciones definidas cuando se elige un dia en particular para ver si esta disponible o no
  82. void _onDaySelected(DateTime day, List events, List holidays) {
  83. print('CALLBACK: _onDaySelected');
  84. setState(() {
  85. _selectedEvents = events;
  86. });
  87. }
  88. void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
  89. print('CALLBACK: _onVisibleDaysChanged');
  90. }
  91. void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
  92. print('CALLBACK: _onCalendarCreated');
  93. }
  94. //Definimos el "look" del area de las citas
  95. @override
  96. Widget build(BuildContext context) {
  97. return Scaffold(
  98. appBar: AppBar(
  99. title: Text(widget.title),
  100. ),
  101. body: Column(
  102. mainAxisSize: MainAxisSize.max,
  103. children: <Widget>[
  104. _buildTableCalendar(
  105. ),
  106. // _buildTableCalendarWithBuilders(),
  107. const SizedBox(height: 8.0),
  108. _buildButtons(),
  109. const SizedBox(height: 8.0),
  110. Expanded(child: _buildEventList()),
  111. ],
  112. ),
  113. );
  114. }
  115. // Simple configuracion de la Tabla de Calendario usando estilos
  116. Widget _buildTableCalendar() {
  117. return TableCalendar(
  118. calendarController: _calendarController,
  119. events: _events,
  120. holidays: _holidays,
  121. startingDayOfWeek: StartingDayOfWeek.monday,
  122. calendarStyle: CalendarStyle(
  123. selectedColor: Colors.lightBlueAccent,
  124. todayColor: Colors.blueAccent,
  125. markersColor: Colors.brown,
  126. outsideDaysVisible: false,
  127. ),
  128. headerStyle: HeaderStyle(
  129. formatButtonTextStyle: TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
  130. formatButtonDecoration: BoxDecoration(
  131. color: Colors.lightBlue,
  132. borderRadius: BorderRadius.circular(16.0),
  133. ),
  134. ),
  135. onDaySelected: _onDaySelected,
  136. onVisibleDaysChanged: _onVisibleDaysChanged,
  137. onCalendarCreated: _onCalendarCreated,
  138. );
  139. }
  140. // Configuraciones detalladas del area de citas como definir dias, meses, etc.
  141. Widget buildTableCalendarWithBuilders() {
  142. return TableCalendar(
  143. locale: 'pl_PL',
  144. calendarController: _calendarController,
  145. events: _events,
  146. holidays: _holidays,
  147. initialCalendarFormat: CalendarFormat.month,
  148. formatAnimation: FormatAnimation.slide,
  149. startingDayOfWeek: StartingDayOfWeek.sunday,
  150. availableGestures: AvailableGestures.all,
  151. availableCalendarFormats: const {
  152. CalendarFormat.month: '',
  153. CalendarFormat.week: '',
  154. },
  155. //Colores de los dias seleccionados
  156. calendarStyle: CalendarStyle(
  157. outsideDaysVisible: false,
  158. weekendStyle: TextStyle().copyWith(color: Colors.blue),
  159. holidayStyle: TextStyle().copyWith(color: Colors.blue),
  160. ),
  161. daysOfWeekStyle: DaysOfWeekStyle(
  162. weekendStyle: TextStyle().copyWith(color: Colors.blue),
  163. ),
  164. headerStyle: HeaderStyle(
  165. centerHeaderTitle: true,
  166. formatButtonVisible: false,
  167. ),
  168. builders: CalendarBuilders(
  169. selectedDayBuilder: (context, date, _) {
  170. //Animacion del Calendario al cambiar el mes
  171. return FadeTransition(
  172. opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
  173. child: Container(
  174. margin: const EdgeInsets.all(4.0),
  175. padding: const EdgeInsets.only(top: 5.0, left: 6.0),
  176. color: Colors.green,
  177. width: 100,
  178. height: 100,
  179. child: Text(
  180. '${date.day}',
  181. style: TextStyle().copyWith(fontSize: 16.0),
  182. ),
  183. ),
  184. );
  185. },
  186. todayDayBuilder: (context, date, _) {
  187. return Container(
  188. margin: const EdgeInsets.all(4.0),
  189. padding: const EdgeInsets.only(top: 5.0, left: 6.0),
  190. color: Colors.amber,
  191. width: 100,
  192. height: 100,
  193. child: Text(
  194. '${date.day}',
  195. style: TextStyle().copyWith(fontSize: 16.0),
  196. ),
  197. );
  198. },
  199. markersBuilder: (context, date, events, holidays) {
  200. final children = <Widget>[];
  201. if (events.isNotEmpty) {
  202. children.add(
  203. Positioned(
  204. right: 1,
  205. bottom: 1,
  206. child: _buildEventsMarker(date, events),
  207. ),
  208. );
  209. }
  210. if (holidays.isNotEmpty) {
  211. children.add(
  212. Positioned(
  213. right: -2,
  214. top: -2,
  215. child: _buildHolidaysMarker(),
  216. ),
  217. );
  218. }
  219. return children;
  220. },
  221. ),
  222. onDaySelected: (date, events, holidays) {
  223. _onDaySelected(date, events, holidays);
  224. _animationController.forward(from: 0.0);
  225. },
  226. onVisibleDaysChanged: _onVisibleDaysChanged,
  227. onCalendarCreated: _onCalendarCreated,
  228. );
  229. }
  230. //Marcador de eventos (aparece debajo de los dias)
  231. Widget _buildEventsMarker(DateTime date, List events) {
  232. return AnimatedContainer(
  233. duration: const Duration(milliseconds: 300),
  234. decoration: BoxDecoration(
  235. shape: BoxShape.rectangle,
  236. color: _calendarController.isSelected(date)
  237. ? Colors.brown[500]
  238. : _calendarController.isToday(date) ? Colors.brown : Colors.blue,
  239. ),
  240. width: 16.0,
  241. height: 16.0,
  242. child: Center(
  243. child: Text(
  244. '${events.length}',
  245. style: TextStyle().copyWith(
  246. color: Colors.green,
  247. fontSize: 12.0,
  248. ),
  249. ),
  250. ),
  251. );
  252. }
  253. Widget _buildHolidaysMarker() {
  254. return Icon(
  255. Icons.add_box,
  256. size: 20.0,
  257. color: Colors.blueGrey,
  258. );
  259. }
  260. Widget _buildButtons() {
  261. final dateTime = _events.keys.elementAt(_events.length - 2);
  262. //Definimos formato del calendario (mes, 2 semanas, semana)
  263. return Column(
  264. children: <Widget>[
  265. Row(
  266. mainAxisSize: MainAxisSize.max,
  267. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  268. children: <Widget>[
  269. RaisedButton(
  270. child: Text('Mes'),
  271. onPressed: () {
  272. setState(() {
  273. _calendarController.setCalendarFormat(CalendarFormat.month);
  274. });
  275. },
  276. ),
  277. RaisedButton(
  278. child: Text('2 Semanas'),
  279. onPressed: () {
  280. setState(() {
  281. _calendarController.setCalendarFormat(CalendarFormat.twoWeeks);
  282. });
  283. },
  284. ),
  285. RaisedButton(
  286. child: Text('Semana'),
  287. onPressed: () {
  288. setState(() {
  289. _calendarController.setCalendarFormat(CalendarFormat.week);
  290. });
  291. },
  292. ),
  293. ],
  294. ),
  295. const SizedBox(height: 8.0),
  296. RaisedButton(
  297. child: Text('Recuerde Cita ${dateTime.day}-${dateTime.month}-${dateTime.year}'),
  298. onPressed: () {
  299. _calendarController.setSelectedDay(
  300. DateTime(dateTime.year, dateTime.month, dateTime.day),
  301. runCallback: true,
  302. );
  303. },
  304. ),
  305. ],
  306. );
  307. }
  308. //Muestra las citas ya creadas
  309. Widget _buildEventList() {
  310. return ListView(
  311. children: _selectedEvents
  312. .map((event) => Container(
  313. decoration: BoxDecoration(
  314. border: Border.all(width: 0.8),
  315. borderRadius: BorderRadius.circular(12.0),
  316. ),
  317. margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
  318. child: ListTile(
  319. title: Text(event.toString()),
  320. onTap: () => print('$event tapped!'),
  321. ),
  322. ))
  323. .toList(),
  324. );
  325. }
  326. }