Skip to content

Instantly share code, notes, and snippets.

@BrianCraig
Forked from chaudharydeepanshu/main.dart
Created August 5, 2022 01:07
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 BrianCraig/23b68df986ef6d1b84bdf46aeed9bbae to your computer and use it in GitHub Desktop.
Save BrianCraig/23b68df986ef6d1b84bdf46aeed9bbae to your computer and use it in GitHub Desktop.
data_grid_jank_example
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(
useMaterial3: true,
),
darkTheme: ThemeData.dark(
useMaterial3: true,
),
themeMode: ThemeMode.system,
home: const Home(),
);
}
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
const int pages = 10000;
class _HomeState extends State<Home> {
late PageController _controller;
// This points always to the mid-element in _list
late int _initialIndex;
@override
void initState() {
super.initState();
// Calculate mid.
_controller =
PageController(initialPage: pages ~/ 2, viewportFraction: 1);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
List months = [
'jan',
'feb',
'mar',
'apr',
'may',
'jun',
'jul',
'aug',
'sep',
'oct',
'nov',
'dec'
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 2,
title: const Text("Data Grid"),
),
body: PageView.builder(
controller: _controller,
itemCount: pages,
itemBuilder: (BuildContext context, int index) {
int relIndex = index - (pages ~/ 2);
return Column(
children: [
Text(months[DateTime(2022, 8 + relIndex, 1).month - 1] +
" " +
DateTime(2022, 8 + relIndex, 1).year.toString()),
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1,
crossAxisCount: 7,
mainAxisExtent: 40,
),
itemCount: 42,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, i) {
return DataWidget(
dataIndex: getDatesForACalendarMonthAsUTC(
dateTime: DateTime(2022, 8 + relIndex, 1))[i],
gridIndex: DateTime(2022, 8 + relIndex, 1),
);
},
),
],
);
}),
);
}
}
class DataWidget extends StatelessWidget {
const DataWidget({Key? key, required this.dataIndex, required this.gridIndex})
: super(key: key);
final DateTime dataIndex;
final DateTime gridIndex;
@override
Widget build(BuildContext context) {
return Row(
children: [
const Expanded(
child: SizedBox(),
),
OutlinedButton(
style: OutlinedButton.styleFrom(
minimumSize: Size.zero,
padding: EdgeInsets.zero,
foregroundColor: Theme.of(context).colorScheme.onSurface,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
side: BorderSide.none,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
).copyWith(elevation: ButtonStyleButton.allOrNull(0.0)),
onPressed: dataIndex.month == gridIndex.month
? () {
//do something
}
: null,
child: SizedBox(
width: 40,
child: Container(
margin: const EdgeInsets.all(4.0),
child: Ink(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).dividerColor, width: 1),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Center(
child: Text(
dataIndex.day.toString(),
style: const TextStyle(),
),
),
),
),
),
),
const Expanded(
child: SizedBox(),
),
],
);
}
}
List<DateTime> getDatesForACalendarMonthAsUTC({required DateTime dateTime}) {
List<DateTime> calendarMonthDaysAsUTC = [];
DateTime currentDateTime = DateTime.utc(dateTime.year, dateTime.month, 1);
DateTime firstDayOfMonthAsUTC =
DateTime.utc(currentDateTime.year, currentDateTime.month, 1);
DateTime lastDayOfMonthAsUTC =
getLastDayOfAMonth(currentDateTime: currentDateTime);
List<DateTime> datesFirstToLastDayOfMonthAsUTC =
getDaysInBetweenIncludingStartEndDate(
startDateTime: firstDayOfMonthAsUTC,
endDateTime: lastDayOfMonthAsUTC);
calendarMonthDaysAsUTC = List.generate(datesFirstToLastDayOfMonthAsUTC.length,
(index) => datesFirstToLastDayOfMonthAsUTC[index]);
int firstDayOfMonthWeekDay = firstDayOfMonthAsUTC.weekday;
for (int i = 1;
i <= firstDayOfMonthWeekDay && firstDayOfMonthWeekDay != 7;
i++) {
calendarMonthDaysAsUTC.insert(
0, firstDayOfMonthAsUTC.subtract(Duration(days: i)));
}
int daysLeftAfterMonthEndDate = 42 - calendarMonthDaysAsUTC.length;
for (int i = 1; i <= daysLeftAfterMonthEndDate; i++) {
calendarMonthDaysAsUTC.add(lastDayOfMonthAsUTC.add(Duration(days: i)));
}
return calendarMonthDaysAsUTC;
}
List<DateTime> getDaysInBetweenIncludingStartEndDate(
{required DateTime startDateTime, required DateTime endDateTime}) {
// Converting dates provided to UTC
// So that all things like DST don't affect subtraction and addition on dates
DateTime startDateInUTC =
DateTime.utc(startDateTime.year, startDateTime.month, startDateTime.day);
DateTime endDateInUTC =
DateTime.utc(endDateTime.year, endDateTime.month, endDateTime.day);
// Created a list to hold all dates
List<DateTime> daysInFormat = [];
// Starting a loop with the initial value as the Start Date
// With an increment of 1 day on each loop
// With condition current value of loop is smaller than or same as end date
for (DateTime i = startDateInUTC;
i.isBefore(endDateInUTC) || i.isAtSameMomentAs(endDateInUTC);
i = i.add(const Duration(days: 1))) {
// Converting back UTC date to Local date before inserting in list
// You can keep in UTC format depending on your case
if (startDateTime.isUtc) {
daysInFormat.add(i);
} else {
daysInFormat.add(DateTime(i.year, i.month, i.day));
}
}
return daysInFormat;
}
DateTime getLastDayOfAMonth({required DateTime currentDateTime}) {
// Getting the 15th-day date of the month for the date provided
DateTime fifteenthDayOfMonth =
DateTime(currentDateTime.year, currentDateTime.month, 15);
// Converting the 15th-day date to UTC
// So that all things like DST don't affect subtraction and addition on date
DateTime twentiethDayOfMonthInUTC = fifteenthDayOfMonth.toUtc();
// Getting a random date of next month by adding 20 days to twentiethDayOfMonthInUTC
// Adding number 20 to any month 15th-day will definitely give a next month date
DateTime nextMonthRandomDateInUTC =
twentiethDayOfMonthInUTC.add(const Duration(days: 20));
DateTime nextMonthRandomDateZeroDayInUTC = DateTime.utc(
nextMonthRandomDateInUTC.year, nextMonthRandomDateInUTC.month, 0);
// Now getting the 0th day date of the next month
// This will give us the current month last date
DateTime nextMonthRandomDateZeroDayInLocal = DateTime(
nextMonthRandomDateInUTC.year, nextMonthRandomDateInUTC.month, 0);
DateTime lastDayOfAMonth;
if (currentDateTime.isUtc) {
lastDayOfAMonth = nextMonthRandomDateZeroDayInUTC;
} else {
lastDayOfAMonth = nextMonthRandomDateZeroDayInLocal;
}
return lastDayOfAMonth;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment