paginetedListView

This commit is contained in:
jantunesmessias 2025-02-10 11:22:48 -03:00
parent f193baebe7
commit 05b3a612ba
9 changed files with 156 additions and 129 deletions

View File

@ -1 +0,0 @@

View File

@ -1,5 +0,0 @@
class DeadCode {
final String? desc;
const DeadCode([this.desc = '']);
}

View File

@ -1 +0,0 @@
export 'anotations.dart';

View File

@ -785,3 +785,5 @@ double computeGradientAlignmentY(double evaluatedAngle) {
}
return double.parse(roundTo(y, 2));
}

View File

@ -56,6 +56,8 @@ Future<void> _initializeSystemSettings() async {
if (kDebugMode) {
//kDebugMode
print('Debug mode');
} else {
print('Release mode');
bool unsentReports =
await FirebaseCrashlytics.instance.checkForUnsentReports();
if (unsentReports) {
@ -66,9 +68,6 @@ Future<void> _initializeSystemSettings() async {
// Não existem relatórios não enviados
print('Todos os relatórios de falhas foram enviados.');
}
} else {
print('Release mode');
await crashlyticsInstance.setCrashlyticsCollectionEnabled(true);
// if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
FlutterError.onError = await crashlyticsInstance.recordFlutterError;

View File

@ -4,7 +4,6 @@ part of 'vehicles_on_the_property.dart';
// ignore: must_be_immutable
class VehicleHistoryScreen extends StatefulWidget {
VehicleHistoryScreen(this.model, {super.key});
late VehicleModel model;
final scaffoldKey = GlobalKey<ScaffoldState>();
@ -12,23 +11,21 @@ class VehicleHistoryScreen extends StatefulWidget {
@override
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
}
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
with Remotable {
@override
void dispose() {
super.dispose();
_scrollController.dispose();
_pagingController.dispose();
}
@override
void initState() {
super.initState();
_initializeScrollController();
_pagingController.addPageRequestListener(_fetch);
}
@override
@ -38,22 +35,19 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
late final double limitedBodyTextSize =
LimitedFontSizeUtil.getBodyFontSize(context);
return Scaffold(
key: widget.scaffoldKey,
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (_hasData == false &&
_pageNumber <= 1 &&
_loading == false)
_buildNoDataFound(context, limitedHeaderTextSize)
else if (_hasData == true || _pageNumber >= 1)
_buildHistoryList(context, limitedBodyTextSize),
if (_hasData == true && _loading == true)
_buildLoadingIndicator(context),
].addToStart(const SizedBox(height: 0)),
),
return Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// if (_hasData == false &&
// _pageNumber <= 1 &&
// _loading == false)
// _buildNoDataFound(context, limitedHeaderTextSize)
// else if (_hasData == true || _pageNumber >= 1)
_buildHistoryList(context, limitedBodyTextSize),
// if (_hasData == true && _loading == true)
// _buildLoadingIndicator(context),
].addToStart(const SizedBox(height: 0)),
);
}
@ -82,30 +76,34 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) {
return Expanded(
child: FutureBuilder<void>(
future: _fetch(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
return ListView.builder(
shrinkWrap: true,
addAutomaticKeepAlives: true,
restorationId: '',
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _wrap.length,
itemBuilder: (context, index) => _generateItems(context, _wrap[index], index),
);
}
},
child: RefreshIndicator(
onRefresh: () async => _pagingController.refresh(),
child: PagedListView<int, dynamic>(
// separatorBuilder: (context, index) => const Divider(),
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate(
animateTransitions: true,
itemBuilder: (context, item, index) =>
_generateItems(context, index, item),
firstPageErrorIndicatorBuilder: (context) => Placeholder(),
newPageErrorIndicatorBuilder: (context) => Placeholder(),
),
),
),
);
}
// ListView.builder(
// shrinkWrap: true,
// addAutomaticKeepAlives: true,
// restorationId: '',
// physics: const BouncingScrollPhysics(),
// controller: _scrollController,
// itemCount: _wrap.length,
// itemBuilder: (context, index) => _generateItems(context, _wrap[index], index),
// ),
Widget _buildLoadingIndicator(BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
@ -118,15 +116,13 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
),
);
}
}
mixin Remotable on State<VehicleHistoryScreen> {
final PagingController<int, dynamic> _pagingController =
PagingController<int, dynamic>(firstPageKey: 1);
late ScrollController _scrollController;
// late ScrollController _scrollController;
double offset = 0.0;
List<dynamic> _wrap = [];
int _pageNumber = 1;
@ -134,37 +130,46 @@ mixin Remotable on State<VehicleHistoryScreen> {
bool _loading = true;
int count = 0;
Future<void> _fetch() async {
Future<void> _fetch(dynamic pageKey) async {
if (!_hasData || !_loading) return;
print('hasHasData');
setState(() => _loading = true);
// setState(() => _loading = true);
try {
var newItems =
await PhpGroup.getVehiclesByProperty.call(pageKey.toString());
final bool isLastPage = newItems.jsonBody == null ||
newItems.jsonBody == [] ||
newItems.jsonBody == '';
var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString());
final List<dynamic> vehicles = response.jsonBody['vehicles'] as List<dynamic>? ?? [];
safeSetState(() => count = response.jsonBody['total_rows'] ?? 0);
if (vehicles.isNotEmpty) {
if (newItems.jsonBody == null) {
} else {
final List<dynamic> vehicles =
newItems.jsonBody['vehicles'] as List<dynamic>? ?? [];
_pagingController.nextPageKey = pageKey + 1;
safeSetState(() => count = newItems.jsonBody['total_rows'] ?? 0);
if (vehicles.isNotEmpty) {
// setState(() {
// _hasData = true;
// _loading = false;
// _wrap.addAll(vehicles);
// });
_pagingController.appendLastPage(vehicles);
return;
}
_showNoMoreDataSnackBar(context);
setState(() {
_hasData = true;
_hasData = false;
_loading = false;
_wrap.addAll(vehicles);
});
print('hasEmpty: ${_wrap.length}');
return;
}
_showNoMoreDataSnackBar(context);
setState(() {
_hasData = false;
_loading = false;
});
print('hasEmpty: ${_wrap.length}');
return;
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s);
LogUtil.requestAPIFailed(
"proccessRequest.php", "", "Consulta de Veículo", e, s);
setState(() {
_hasData = false;
_loading = false;
@ -202,37 +207,48 @@ mixin Remotable on State<VehicleHistoryScreen> {
);
}
Widget? _generateItems(BuildContext context, dynamic snapshot, int index) {
if (index == 0) return _buildHeader(context);
final bool? isOwner = snapshot['isOwnerVehicle'];
final IconData? iconData = isOwner == true ? Symbols.garage : Symbols.directions_car;
final FreCardIcon? cardIcon = isOwner != null
? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10))
: null;
Widget _generateItems(BuildContext context, int index, dynamic item) {
log('item: $item');
final String? tag = snapshot['tag'];
final bool containTag = tag.isNotNullAndEmpty;
final Map<String, String> labelsHashMap = _generateLabelsHashMap(context, snapshot, tag, containTag);
// return Placeholder();
final List<Map<String, Color>> statusHashMapList = _generateStatusHashMapList(snapshot);
// if (index == 0) return _buildHeader(context);
Future<void> onTapCardItemAction() async {
_handleCardItemTap(context, cardIcon, snapshot);
}
final bool? isOwner = item['isOwnerVehicle'];
final IconData? iconData =
isOwner == true ? Symbols.garage : Symbols.directions_car;
final FreCardIcon? cardIcon = isOwner != null
? FreCardIcon(
height: 50,
width: 100,
icon: Icon(iconData, size: 80, opticalSize: 10))
: null;
final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap<String, Color>.from(map)).toList();
final length = statusLinkedHashMap.expand((e) => [e.length]);
final String? tag = item['tag'];
final bool containTag = tag.isNotNullAndEmpty;
final Map<String, String> labelsHashMap =
_generateLabelsHashMap(context, item, tag, containTag);
return CardItemTemplateComponentWidget(
icon: cardIcon,
labelsHashMap: labelsHashMap,
statusHashMap: statusHashMapList,
onTapCardItemAction: onTapCardItemAction,
itemWidthFactor: length == 1 ? 0.25 : 0.50,
);
final List<Map<String, Color>> statusHashMapList =
_generateStatusHashMapList(item);
Future<void> onTapCardItemAction() async {
_handleCardItemTap(context, cardIcon, item);
}
final statusLinkedHashMap = statusHashMapList
.map((map) => LinkedHashMap<String, Color>.from(map))
.toList();
final length = statusLinkedHashMap.expand((e) => [e.length]);
return CardItemTemplateComponentWidget(
icon: cardIcon,
labelsHashMap: labelsHashMap,
statusHashMap: statusHashMapList,
onTapCardItemAction: onTapCardItemAction,
itemWidthFactor: length == 1 ? 0.25 : 0.50,
);
}
Map<String, String> _generateLabelsHashMap(BuildContext context,
Map<String, dynamic> uItem, String? tag, bool containTag) {
@ -249,17 +265,16 @@ mixin Remotable on State<VehicleHistoryScreen> {
};
}
List<Map<String, Color>> _generateStatusHashMapList(
Map<String, dynamic> uItem) {
final statusHashMap =
widget.model.generateStatusColorMap(uItem, false);
List<Map<String, Color>> _generateStatusHashMapList(
Map<String, dynamic> uItem) {
final statusHashMap = widget.model.generateStatusColorMap(uItem, false);
return statusHashMap != null ? [statusHashMap] : [];
}
Future<void> _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon,
Map<String, dynamic> uItem) async {
try {
final dialogContent = widget.model.buildVehicleDetails(
final dialogContent = widget.model.buildVehicleDetails(
icon: cardIcon,
item: uItem,
context: context,
@ -274,7 +289,7 @@ mixin Remotable on State<VehicleHistoryScreen> {
).whenComplete(() {
safeSetState(() {
_pageNumber = 1;
_fetch();
_fetch(1);
});
});
} catch (e, s) {
@ -289,27 +304,26 @@ mixin Remotable on State<VehicleHistoryScreen> {
}
void _initializeScrollController() {
_scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset)
..addListener(() {
print('ScrollController');
if(!_hasData) return;
if
// (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent)
(_scrollController.position.atEdge && _scrollController.position.pixels != 0)
{
print('ScrollController -> loadMore');
offset = _scrollController.offset;
_loadMore();
}
},);
}
void _loadMore() {
if (_hasData) {
_pageNumber+=1;
_loading = true;
_fetch();
}
// _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset)
// ..addListener(() {
// print('ScrollController');
// if(!_hasData) return;
// if
// // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent)
// (_scrollController.position.atEdge && _scrollController.position.pixels != 0)
// {
// print('ScrollController -> loadMore');
// offset = _scrollController.offset;
// _loadMore();
// }
// },);
}
// void _loadMore() {
// if (_hasData) {
// _pageNumber+=1;
// _loading = true;
// _fetch(_pageNumber);
// }
// }
}

View File

@ -16,6 +16,7 @@ import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/license_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:material_symbols_icons/symbols.dart';
part 'vehicle_history_screen.dart';

View File

@ -1 +0,0 @@

View File

@ -15,6 +15,7 @@ dependencies:
sdk: flutter
auto_size_text: 3.0.0
barcode_widget: ^2.0.4
infinite_scroll_pagination: ^4.1.0
cached_network_image: ^3.4.0
firebase_core: ^3.4.0
flutter_inappwebview: ^6.0.0
@ -103,7 +104,25 @@ dependencies:
# crypto: ^3.0.5
freezed_annotation: ^2.4.4
package_info_plus: ^8.1.1
sliver_tools: ^0.2.12
# json_annotation: ^4.9.0
base:
git:
url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git'
path: 'packages/base'
components:
git:
url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git'
path: 'packages/components'
templates:
git:
url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git'
path: 'packages/templates'
theme:
git:
url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git'
path: 'packages/theme'
dependency_overrides:
http: 1.2.1