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)); return double.parse(roundTo(y, 2));
} }

View File

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

View File

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

View File

@ -1 +0,0 @@

View File

@ -15,6 +15,7 @@ dependencies:
sdk: flutter sdk: flutter
auto_size_text: 3.0.0 auto_size_text: 3.0.0
barcode_widget: ^2.0.4 barcode_widget: ^2.0.4
infinite_scroll_pagination: ^4.1.0
cached_network_image: ^3.4.0 cached_network_image: ^3.4.0
firebase_core: ^3.4.0 firebase_core: ^3.4.0
flutter_inappwebview: ^6.0.0 flutter_inappwebview: ^6.0.0
@ -103,7 +104,25 @@ dependencies:
# crypto: ^3.0.5 # crypto: ^3.0.5
freezed_annotation: ^2.4.4 freezed_annotation: ^2.4.4
package_info_plus: ^8.1.1 package_info_plus: ^8.1.1
sliver_tools: ^0.2.12
# json_annotation: ^4.9.0 # 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: dependency_overrides:
http: 1.2.1 http: 1.2.1