flex_widgets 0.0.1+4
flex_widgets: ^0.0.1+4 copied to clipboard
This is a flutter package for flex widgets.
example/lib/main.dart
import 'dart:core';
import 'package:example/dashboard.dart';
import 'package:flex_widgets/flex_widgets.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
Widget? getPageWidget(RouteSettings settings) {
if (settings.name == null) {
return null;
}
final uri = Uri.parse(settings.name!);
switch (uri.path) {
case '/':
return const Dashboard();
case '/services':
return const ServiceBody();
default:
return null;
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(360, 690),
minTextAdapt: true,
splitScreenMode: true,
builder: (context, child) {
return FlexResponsiveApp(
builder: (context) {
// return FlexMacosApp(
// title: 'Flutter Demo',
// debugShowCheckedModeBanner: false,
// theme: FlexMacosThemeData.light(),
// home: const HomeMacosApp(),
// );
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// routes: {
// ScreenTwo.routeName: (context) => const ScreenTwo(tag: ''),
// MyHomePage.routeName: (context) => const MyHomePage(title: ''),
// },
// home: const MyHomePage(title: 'Flutter Demo Home Page'),
initialRoute: '/',
onGenerateRoute: (settings) {
final page = getPageWidget(settings);
if (page != null) {
return PageRouteBuilder(
settings: settings,
pageBuilder: (_, __, ___) => page,
transitionsBuilder: (_, anim, __, child) {
return FadeTransition(
opacity: anim,
child: child,
);
},
);
}
return null;
},
);
},
);
},
// child: FlexScreenTypeLayout.builder(
// breakpoints: FlexScreenBreakpoints(
// mobile: 375.0,
// tablet: 600.0,
// desktop: 1024.0,
// watch: 300.0,
// ),
// mobile: (context) => GestureDetector(
// onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
// child: FlexMacosApp(
// title: 'Flutter Demo',
// debugShowCheckedModeBanner: false,
// theme: FlexMacosThemeData.light(),
// home: const HomeMacosApp(
//
// ),
// ),
// ),
// ),
);
}
}
class PageScreen extends StatelessWidget {
const PageScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page Screen'),
),
body: FlexMacosTheme(
data: FlexMacosThemeData(),
child: FlexPushButton(
onPressed: () {},
controlSize: ControlSize.large,
child: const FlexText(text: 'subtitle'),
),
),
bottomNavigationBar: NavigationBar(
selectedIndex: 0,
destinations: const [
NavigationDestination(
icon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.search),
label: 'Search',
),
NavigationDestination(
icon: Icon(Icons.add),
label: 'Add',
),
NavigationDestination(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
),
);
}
}
class MyHomePage extends StatefulWidget {
static const routeName = '/home';
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class FlexCustomScrollView extends StatelessWidget {
const FlexCustomScrollView({
super.key,
this.slivers = const <Widget>[],
this.scrollDirection = Axis.vertical,
this.sliverAppBar,
});
final List<Widget> slivers;
final Axis scrollDirection;
final SliverAppBar? sliverAppBar;
@override
Widget build(BuildContext context) {
return CustomScrollView(
scrollDirection: scrollDirection,
slivers: [
sliverAppBar ?? const SliverAppBar(),
...slivers,
],
// reverse: reverse,
// restorationId: restorationId,
// physics: physics,
// scrollBehavior: scrollBehavior,
// keyboardDismissBehavior: keyboardDismissBehavior,
// semanticChildCount: semanticChildCount,
// dragStartBehavior: dragStartBehavior,
);
}
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
int _selectedIndex = 0;
Stream stream = Stream.value([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
@override
Widget build(BuildContext context) {
return Scaffold(
body: FlexCustomScrollView(
sliverAppBar: SliverAppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
slivers: [
// SliverToBoxAdapter(
// child: Column(
// // mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Checkbox.adaptive(
// value: true,
// onChanged: (value) {},
// ),
// const CupertinoTextField(),
// // 5.5.height,
// const FlexFormField.withLable(
// labelName: 'Lable',
// hintText: '',
// ),
// // 5.5.height,
// FlexCheckboxListTile(
// title: 'Loqman',
// value: false,
// onChanged: (value) {},
// ),
// // FlexContainer(
// // height: 0.1,
// // color: Colors.red,
// // child: FlexText.h0(
// // text: 'text',
// // color: Colors.white,
// // ),
// // ),
// FlexDropDown(
// items: const [
// DropdownMenuItem(
// value: 'Loqman',
// child: Text('Loqman'),
// ),
// DropdownMenuItem(
// value: 'Yahyaa',
// child: Text('Yahyaa'),
// ),
// ],
// label: 'Loqman',
// onChanged: (value) {},
// ),
// const FlexExpansionTile(
// title: Text('Loqman'),
// ),
// FlexConditionalBuilder(
// condition: _counter.isEven,
// fallback: (context) {
// return const Text('Odd');
// },
// builder: (context) => const Text('Even'),
// ),
// Text(
// '$_counter',
// style: Theme.of(context).textTheme.headlineMedium,
// ),
// const FlexImageNetwork(
// image: 'https://picsum.photos/200/300',
// height: 200,
// width: 200,
// ),
// 1.0.height,
// FlexOutLineButton(
// onPressed: () {
// context.showFlexToast(
// child: const FlexText(text: 'Loqman Toast'),
// bgColor: FlexColor.warning,
// isDismissable: true,
// );
// },
// text: 'FlexToast',
// backgroundColor: Colors.red,
// foregroundColor: Colors.white,
// borderColor: Colors.black,
// minimumSize: Size(context.width / 2, 0.0),
// ),
// 1.0.height,
// FlexOutLineButtonWithIcon(
// onPressed: () {
// context.showFlexSnackBar(
// text: 'Flex SnackBar',
// color: FlexColor.warning,
// textColor: Colors.black,
// behavior: SnackBarBehavior.fixed,
// );
// },
// label: 'text',
// labelColor: Colors.white,
// icon: const Icon(Icons.add),
// backgroundColor: Colors.red,
// foregroundColor: Colors.white,
// minimumSize: Size(context.width / 2, 0.0),
// ),
// 1.0.height,
// const FlexEmpty(),
// 1.0.height,
// const FlexLoading(
// type: FlexLoadingType.wanderingCubes,
// ),
// 15.0.height,
// const FlexLoadingAlertDialog(
// color: Colors.red,
// type: FlexLoadingType.circle,
// ),
// 5.0.height,
// const FlexNoMoreData(index: 1, hasMoreData: false, limit: 1),
// 5.0.height,
// FlexTreeView(
// nodes: [
// FlexTreeNode(
// label: '${'eg'.countryFlag} Egypt',
// icon: const Icon(Icons.folder),
// children: [
// FlexTreeNode(
// onTap: () {
// context.showFlexLoading();
// },
// label: 'label',
// icon: const Icon(Icons.folder),
// ),
// FlexTreeNode(
// onTap: () {},
// label: 'label',
// icon: const Icon(Icons.folder),
// ),
// ],
// ),
// ],
// ),
// 5.0.height,
// ],
// ),
// ),
// SliverList.builder(
// itemCount: 50,
// itemBuilder: (context, index) {
// return ListTile(
// title: Hero(
// tag: '${index + 1}',
// createRectTween: (begin, end) {
// return MaterialRectCenterArcTween(
// begin: Rect.fromCircle(
// center: begin!.bottomRight,
// radius: 10,
// ),
// end: Rect.fromCircle(
// center: end!.bottomLeft,
// radius: 10,
// ),
// );
// },
// child: FlexText.h3(
// text: 'title ${index + 1}',
// ),
// ),
// trailing: FlexMacosTheme(
// data: FlexMacosThemeData(),
// child: FlexPushButton(
// onPressed: () {},
// controlSize: ControlSize.large,
// child: const FlexText(text: 'subtitle'),
// ),
// ),
// onTap: () {
// AppNavigator.navigatorTo(
// context: context,
// back: true,
// // routeName: ScreenTwo.routeName,
// // arguments: '${index + 1}',
// widget: ScreenTwo(
// tag: '${index + 1}',
// ),
// );
// },
// );
// },
// ),
SliverToBoxAdapter(
child: Column(
children: [
// SizedBox(
// height: context.height / 2,
// child: FlexMacosTheme(
// data: FlexMacosThemeData(),
// child: FlexSidebarItems(
// items: const [
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// FlexSidebarItem(
// label: Text('label'),
// leading: Icon(Icons.folder),
// ),
// ],
// currentIndex: _selectedIndex,
// onChanged: (index) {
// setState(() {
// _selectedIndex = index;
// });
// },
// ),
// ),
// ),
FlexMacosDatePicker(
onDateChanged: (date) {},
),
FlexMacosTimePicker(
onTimeChanged: (time) {},
),
TextButton(
onPressed: () {
FlexNavigator.navigatorTo(
context: context,
back: true,
widget: const Dashboard(),
);
},
child: const Text('Dashboard'),
),
FlexMacosPopupButton(
popupColor: Colors.red,
value: 'item 1',
hint: const Text('hint'),
items: List.generate(5, (index) {
return FlexMacosPopupMenuItem(
value: 'item $index',
child: Text('item $index'),
);
}),
onChanged: (value) {
print(value);
},
),
SizedBox(
height: context.height / 2,
child: FlexMacosTheme(
data: FlexMacosThemeData(),
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
title: Hero(
tag: '${index + 1}',
createRectTween: (begin, end) {
return MaterialRectCenterArcTween(
begin: Rect.fromCircle(
center: begin!.bottomRight,
radius: 10,
),
end: Rect.fromCircle(
center: end!.bottomLeft,
radius: 10,
),
);
},
child: FlexText.h3(
text: 'title ${index + 1}',
),
),
trailing: FlexMacosTheme(
data: FlexMacosThemeData(
primaryColor: Colors.red,
),
child: FlexPushButton(
onPressed: () {},
controlSize: ControlSize.large,
color: FlexMacosColors.appleBlue,
child: const FlexText(text: 'subtitle'),
),
),
onTap: () {
// AppNavigator.navigatorTo(
// context: context,
// back: true,
// // routeName: ScreenTwo.routeName,
// // arguments: '${index + 1}',
// widget: ScreenTwo(
// tag: '${index + 1}',
// ),
// );
FlexNavigator.navigate(
context: context,
navigatorType: FlexNavigatorType.push,
widget: ScreenTwo(
tag: '${index + 1}',
),
);
},
);
},
),
),
),
],
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class ScreenTwo extends StatelessWidget {
static const routeName = '/2';
const ScreenTwo({super.key, required this.tag});
final String tag;
@override
Widget build(BuildContext context) {
// final tag = ModalRoute.of(context)!.settings.arguments as String;
return Hero(
tag: tag,
// flightShuttleBuilder: (flightContext, animation, flightDirection,
// fromHeroContext, toHeroContext) {
// final Hero toHero = toHeroContext.widget as Hero;
// return FadeTransition(
// opacity: animation.drive(
// Tween<double>(begin: 0.0, end: 1.0).chain(
// CurveTween(
// curve: const Interval(0.0, 1.0, curve: Curves.easeInOutBack),
// ),
// ),
// ),
// child: toHero.child,
// );
// },
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
const SliverAppBar(
title: Text('Screen Two'),
),
SliverToBoxAdapter(
child: ListTile(
title: FlexText.h0(
text: 'Screen Two',
),
onTap: () {},
),
),
];
},
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: FlexText.h0(
text: tag,
textAlign: TextAlign.center,
),
),
],
),
),
),
);
}
}
class FlexDialog extends StatelessWidget {
const FlexDialog({
super.key,
required this.title,
required this.content,
required this.actions,
});
final String title;
final FlexText content;
final List<Widget> actions;
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(title),
content: content,
actions: actions,
);
}
}
class OnHoverText extends StatefulWidget {
const OnHoverText({super.key, required this.builder});
final Widget Function(bool isHovered) builder;
@override
State<OnHoverText> createState() => _OnHoverTextState();
}
class _OnHoverTextState extends State<OnHoverText> {
bool isHover = false;
@override
Widget build(BuildContext context) {
final hoveredTransform = Matrix4.identity()
..translate(5, 0, 0)
..scale(1.0);
final transform = isHover ? hoveredTransform : Matrix4.identity();
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (event) => onEntered(true),
onExit: (event) => onEntered(false),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
// curve: Sprung.overDamped,
transform: transform,
child: widget.builder(isHover),
),
);
}
void onEntered(bool isHovering) {
setState(() {
isHover = isHovering;
});
}
}
class HoverToggle extends StatefulWidget {
const HoverToggle({
super.key,
required this.child,
required this.hoverChild,
required this.size,
this.mode = HoverMode.replace,
});
final Widget child;
final Widget hoverChild;
final HoverMode mode;
final Size size;
@override
State<HoverToggle> createState() => _HoverToggleState();
}
class _HoverToggleState extends State<HoverToggle> with MaterialStateMixin {
@override
Widget build(BuildContext context) {
return SizedBox.fromSize(
size: widget.size,
child: MouseRegion(
cursor: isHovered ? SystemMouseCursors.click : MouseCursor.defer,
onEnter: (_) => setMaterialState(MaterialState.hovered, true),
onExit: (_) => setMaterialState(MaterialState.hovered, false),
child: widget.mode == HoverMode.replace
? _buildReplacedChildren()
: _buildChildrenStack(),
),
);
}
Widget _buildChildrenStack() {
Widget child =
isHovered ? Opacity(opacity: 0.2, child: widget.child) : widget.child;
return Stack(
children: [
child,
if (isHovered) widget.hoverChild,
],
);
}
Widget _buildReplacedChildren() {
return isHovered ? widget.hoverChild : widget.child;
}
}
enum HoverMode { replace, overlay }
class FlexListDataTable<T> extends StatefulWidget {
const FlexListDataTable({
super.key,
required this.columns,
required this.fields,
required this.sortAscending,
required this.onEditTap,
required this.onDeleteTap,
required this.listOfData,
this.sortColumnIndex,
this.onSort,
this.actionWidget,
this.actionEditWidget,
this.actionDeleteWidget,
this.onActionTap,
this.isScrollable = false,
this.headingRowHeight = 45.0,
this.headingRowColor = Colors.redAccent,
this.columnTextFontSize = 15.0,
this.columnTextBold = true,
this.columnSpacing = 30.0,
});
final List<String> columns;
final List<String> fields;
final bool sortAscending;
final int? sortColumnIndex;
final List<T> listOfData;
final Function onEditTap;
final Function onDeleteTap;
final Function? onSort;
final double headingRowHeight;
final Color headingRowColor;
final double columnTextFontSize;
final bool columnTextBold;
final double columnSpacing;
final Widget? actionWidget;
final Widget? actionEditWidget;
final Widget? actionDeleteWidget;
final Function? onActionTap;
final bool isScrollable;
@override
State<FlexListDataTable> createState() => _FlexListDataTableState();
}
class _FlexListDataTableState extends State<FlexListDataTable> {
List<DataRow> rows = [];
late List<dynamic> listOfData;
@override
void initState() {
super.initState();
listOfData = widget.listOfData.map((model) {
return rows.add(
DataRow(
cells: widget.fields.map((field) {
if (field == "") {
List<Widget> actionWidgets = [];
if (widget.actionEditWidget == null) {
actionWidgets.add(
GestureDetector(
child: const Icon(
Icons.edit,
color: Colors.black,
),
onTap: () {
widget.onEditTap(model);
},
),
);
} else {
actionWidgets.add(
GestureDetector(
child: widget.actionEditWidget,
onTap: () {
widget.onEditTap(model);
},
),
);
}
if (widget.actionDeleteWidget == null) {
actionWidgets.add(
GestureDetector(
child: const Icon(
Icons.delete,
color: Colors.red,
),
onTap: () {
widget.onDeleteTap(model);
},
),
);
} else {
actionWidgets.add(
GestureDetector(
child: widget.actionDeleteWidget,
onTap: () {
widget.onDeleteTap(model);
},
),
);
}
if (widget.actionWidget != null) {
actionWidgets.add(
GestureDetector(
child: widget.actionWidget,
onTap: () {
widget.onActionTap!(model);
},
),
);
}
return DataCell(
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.end,
children: actionWidgets,
),
),
);
} else {
return DataCell(FlexText(
text: _getValue(model, field).toString(),
));
}
}).toList(),
),
);
}).toList();
}
dynamic _getValue(Map<String, dynamic> mapRep, String propertyName) {
if (mapRep.containsKey(propertyName)) {
return mapRep[propertyName] ?? "";
}
throw ArgumentError('Property not found : $propertyName');
}
@override
Widget build(BuildContext context) {
return FlexDataTable(
columns: widget.columns,
fields: widget.fields,
sortAscending: widget.sortAscending,
listOfData: listOfData,
onEditTap: widget.onEditTap,
onDeleteTap: widget.onDeleteTap,
rows: rows,
onSort: widget.onSort,
headingRowHeight: widget.headingRowHeight,
headingRowColor: widget.headingRowColor,
columnTextFontSize: widget.columnTextFontSize,
columnTextBold: widget.columnTextBold,
columnSpacing: widget.columnSpacing,
isScrollable: widget.isScrollable,
);
}
}
class FlexDataTable extends StatefulWidget {
const FlexDataTable({
super.key,
required this.columns,
required this.fields,
required this.sortAscending,
required this.onEditTap,
required this.onDeleteTap,
required this.rows,
required this.listOfData,
this.sortColumnIndex,
this.onSort,
this.headingRowHeight = 45.0,
this.headingRowColor = Colors.redAccent,
this.columnTextFontSize = 15.0,
this.columnTextBold = true,
this.columnSpacing = 30.0,
this.isScrollable = false,
});
final List<String> columns;
final List<String> fields;
final bool sortAscending;
final int? sortColumnIndex;
final List listOfData;
final Function onEditTap;
final Function onDeleteTap;
final List<DataRow> rows;
final Function? onSort;
final double headingRowHeight;
final Color headingRowColor;
final double columnTextFontSize;
final bool columnTextBold;
final double columnSpacing;
final bool isScrollable;
@override
State<FlexDataTable> createState() => _FlexDataTableState();
}
class _FlexDataTableState extends State<FlexDataTable> {
late Widget table;
@override
void initState() {
super.initState();
table = DataTable(
headingRowColor: MaterialStateColor.resolveWith(
(states) => widget.headingRowColor,
),
headingRowHeight: widget.headingRowHeight,
sortAscending: widget.sortAscending,
sortColumnIndex: widget.sortColumnIndex,
columns: widget.columns.map(
(columnName) {
return DataColumn(
label: FlexText(
text: columnName,
fontSize: widget.columnTextFontSize,
fontWeight: widget.columnTextBold ? FontWeight.w900 : null,
),
onSort: (columnIndex, ascending) {
widget.onSort!(
columnIndex, widget.fields[columnIndex], ascending);
},
);
},
).toList(),
columnSpacing: widget.columnSpacing,
rows: widget.rows,
);
}
@override
Widget build(BuildContext context) {
return widget.isScrollable
? SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: table,
),
)
: SizedBox(width: context.width, child: table);
}
}
class ListUtils {
ListUtils._internal();
static final ListUtils instance = ListUtils._internal();
Widget buildDataTable<T>({
required BuildContext context,
required List<String> columns,
required List<String> fields,
required bool sortAscending,
required int? sortColumnIndex,
required dynamic listOfData,
required Function onEditTap,
required Function onDeleteTap,
required Function onSort,
double headingRowHeight = 45,
Color headingRowColor = Colors.redAccent,
double columnTextFontSize = 15,
bool columnTextBold = true,
double columnSpacing = 30,
Widget? actionWidget,
Widget? actionEditWidget,
Widget? actionDeleteWidget,
Function? onActionTap,
bool isScrollable = false,
// bool refreshIndicator = false,
// Key refreshkey,
// Function onRefresh,
}) {
List<DataRow> rows = [];
listOfData.forEach(
(model) {
rows.add(
DataRow(
cells: fields.map(
(field) {
if (field == "") {
List<Widget> actionWidgets = [];
if (actionEditWidget == null) {
actionWidgets.add(
GestureDetector(
child: const Icon(
Icons.edit,
color: Colors.black,
),
onTap: () {
onEditTap(model);
},
),
);
} else {
actionWidgets.add(
GestureDetector(
child: actionEditWidget,
onTap: () {
onEditTap(model);
},
),
);
}
if (actionDeleteWidget == null) {
actionWidgets.add(
GestureDetector(
child: const Icon(
Icons.delete,
color: Colors.red,
),
onTap: () {
onDeleteTap(model);
},
),
);
} else {
actionWidgets.add(
GestureDetector(
child: actionDeleteWidget,
onTap: () {
onDeleteTap(model);
},
),
);
}
if (actionWidget != null) {
actionWidgets.add(
GestureDetector(
child: actionWidget,
onTap: () {
onActionTap!(model);
},
),
);
}
return DataCell(
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.end,
children: actionWidgets,
),
),
);
} else {
return DataCell(
Text(
_getValue(model, field).toString(),
),
);
}
},
).toList(),
),
);
},
);
// return refreshIndicator
// ? Container(
// child: RefreshIndicator(
// key: refreshkey,
// onRefresh: () {
// return onRefresh();
// },
// child: _dataTable<T>(
// context,
// columns,
// fields,
// sortAscending,
// sortColumnIndex,
// listOfData,
// onEditTap,
// onDeleteTap,
// rows,
// onSort: onSort,
// headingRowHeight: headingRowHeight,
// headingRowColor: headingRowColor,
// columnTextFontSize: columnTextFontSize,
// columnTextBold: columnTextBold,
// columnSpacing: columnSpacing,
// ),
// ),
// )
return _dataTable<T>(
context,
columns,
fields,
sortAscending,
sortColumnIndex,
listOfData,
onEditTap,
onDeleteTap,
rows,
onSort: onSort,
headingRowHeight: headingRowHeight,
headingRowColor: headingRowColor,
columnTextFontSize: columnTextFontSize,
columnTextBold: columnTextBold,
columnSpacing: columnSpacing,
isScrollable: isScrollable,
);
}
Widget _dataTable<T>(
BuildContext context,
List<String> columns,
List<String> fields,
bool sortAscending,
int? sortColumnIndex,
dynamic listOfData,
Function onEditTap,
Function onDeleteTap,
List<DataRow> rows, {
Function? onSort,
double headingRowHeight = 45,
Color headingRowColor = Colors.redAccent,
double columnTextFontSize = 15,
bool columnTextBold = true,
double columnSpacing = 30,
bool isScrollable = false,
}) {
Widget table = DataTable(
headingRowColor: MaterialStateColor.resolveWith(
(states) => headingRowColor,
),
headingRowHeight: headingRowHeight,
sortAscending: sortAscending,
sortColumnIndex: sortColumnIndex,
columns: columns.map(
(columnName) {
return DataColumn(
label: Text(
columnName,
style: TextStyle(
fontSize: columnTextFontSize,
fontWeight: columnTextBold ? FontWeight.w900 : null,
),
),
onSort: (columnIndex, ascending) {
onSort!(columnIndex, fields[columnIndex], ascending);
},
);
},
).toList(),
columnSpacing: columnSpacing,
rows: rows,
);
return isScrollable
? SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: table,
),
)
: SizedBox(width: MediaQuery.of(context).size.width, child: table);
}
static dynamic _getValue(Map<String, dynamic> mapRep, String propertyName) {
if (mapRep.containsKey(propertyName)) {
return mapRep[propertyName] ?? "";
}
throw ArgumentError('Property not found : $propertyName');
}
}