From 9c40299af6c4bd25f92049bc576ef528a537b13b Mon Sep 17 00:00:00 2001 From: mtnbnz <26857259+mtnbnz@users.noreply.github.com> Date: Fri, 25 Jul 2025 20:26:40 +0200 Subject: [PATCH] Fix FAB covering list items --- lib/alarm/screens/alarm_screen.dart | 8 ++--- lib/clock/screens/clock_screen.dart | 1 + lib/common/widgets/fab.dart | 32 ++++++++++++++++--- lib/common/widgets/list/custom_list_view.dart | 10 ++++-- .../widgets/list/persistent_list_view.dart | 16 ++++++---- lib/stopwatch/screens/stopwatch_screen.dart | 1 + lib/timer/screens/timer_screen.dart | 2 +- 7 files changed, 50 insertions(+), 20 deletions(-) diff --git a/lib/alarm/screens/alarm_screen.dart b/lib/alarm/screens/alarm_screen.dart index df76acd3..47414c7c 100644 --- a/lib/alarm/screens/alarm_screen.dart +++ b/lib/alarm/screens/alarm_screen.dart @@ -23,7 +23,6 @@ import 'package:clock_app/settings/types/setting.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - class AlarmScreen extends StatefulWidget { const AlarmScreen({super.key, this.actionController}); @@ -130,10 +129,8 @@ class _AlarmScreenState extends State { DateTime? nextScheduleDateTime = alarm.currentScheduleDateTime; if (nextScheduleDateTime == null) return; ScaffoldMessenger.of(context).showSnackBar(getThemedSnackBar( - context, - getNewAlarmText(context, alarm), - fab: true, - navBar: true)); + context, getNewAlarmText(context, alarm), + fab: true, navBar: true)); }); } @@ -314,6 +311,7 @@ class _AlarmScreenState extends State { listFilters: _getListFilterItems(), customActions: _getCustomActions(), sortOptions: _showSort.value ? alarmSortOptions : [], + bottomInset: FAB.bottomInset(context), ), FAB( onPressed: handleAddAlarmActon, diff --git a/lib/clock/screens/clock_screen.dart b/lib/clock/screens/clock_screen.dart index 7d14431e..405aaabf 100644 --- a/lib/clock/screens/clock_screen.dart +++ b/lib/clock/screens/clock_screen.dart @@ -104,6 +104,7 @@ class _ClockScreenState extends State { placeholderText: "No cities added", isDuplicateEnabled: false, isSelectable: true, + bottomInset: FAB.bottomInset(context), ), ), ]), diff --git a/lib/common/widgets/fab.dart b/lib/common/widgets/fab.dart index f8a96317..30d5a6f4 100644 --- a/lib/common/widgets/fab.dart +++ b/lib/common/widgets/fab.dart @@ -7,6 +7,10 @@ import 'package:flutter/material.dart'; enum FabPosition { bottomLeft, bottomRight } +const double _kIconSize = 24.0; +const double _kMaterialStyleBottomPadding = 20.0; +const double _kPadding = 16.0; + class FAB extends StatefulWidget { const FAB({ super.key, @@ -27,6 +31,24 @@ class FAB extends StatefulWidget { @override State createState() => _FABState(); + + static double bottomInset( + BuildContext context, { + int size = 1, + double bottomPadding = 0, + }) { + ThemeData theme = Theme.of(context); + ThemeSettingExtension themeSettings = + theme.extension()!; + + const paddingHeight = 2 * _kPadding; + final iconHeight = _kIconSize * size; + final totalHeight = bottomPadding + paddingHeight + iconHeight; + + return themeSettings.useMaterialStyle + ? totalHeight + _kMaterialStyleBottomPadding + : totalHeight; + } } class _FABState extends State { @@ -65,27 +87,27 @@ class _FABState extends State { : widget.position; double bottomPadding = themeSettings.useMaterialStyle - ? widget.bottomPadding + 20 + ? widget.bottomPadding + _kMaterialStyleBottomPadding : widget.bottomPadding; return Positioned( bottom: bottomPadding, right: position == FabPosition.bottomRight - ? 16 + (widget.index * 24 * widget.size) + widget.index * 36 + ? 16 + (widget.index * _kIconSize * widget.size) + widget.index * 36 : null, left: position == FabPosition.bottomLeft - ? 16 + (widget.index * 24 * widget.size) + widget.index * 36 + ? 16 + (widget.index * _kIconSize * widget.size) + widget.index * 36 : null, child: CardContainer( elevationMultiplier: 2, color: colorScheme.primary, onTap: widget.onPressed, child: Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(_kPadding), child: Icon( widget.icon, color: colorScheme.onPrimary, - size: 24 * widget.size, + size: _kIconSize * widget.size, ), ), ), diff --git a/lib/common/widgets/list/custom_list_view.dart b/lib/common/widgets/list/custom_list_view.dart index 21faa7c2..ea658c65 100644 --- a/lib/common/widgets/list/custom_list_view.dart +++ b/lib/common/widgets/list/custom_list_view.dart @@ -37,6 +37,7 @@ class CustomListView extends StatefulWidget { this.initialSortIndex = 0, this.onChangeSortIndex, this.header, + this.bottomInset = 0, }); final List items; @@ -60,6 +61,7 @@ class CustomListView extends StatefulWidget { final Function(int index)? onChangeSortIndex; final Widget? header; final bool isSelectable; + final double bottomInset; @override State createState() => _CustomListViewState(); @@ -387,8 +389,12 @@ class _CustomListViewState proxyDecorator: (widget, index, animation) => reorderableListDecorator(context, widget), items: currentList, - padding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: EdgeInsets.only( + left: 16, + top: 8, + right: 16, + bottom: widget.bottomInset + 8, + ), isSameItem: (a, b) => a.id == b.id, scrollDirection: Axis.vertical, itemBuilder: _getItemBuilder(), diff --git a/lib/common/widgets/list/persistent_list_view.dart b/lib/common/widgets/list/persistent_list_view.dart index 09636b20..8f40640e 100644 --- a/lib/common/widgets/list/persistent_list_view.dart +++ b/lib/common/widgets/list/persistent_list_view.dart @@ -2,6 +2,7 @@ import 'package:clock_app/common/types/list_controller.dart'; import 'package:clock_app/common/types/list_filter.dart'; import 'package:clock_app/common/types/list_item.dart'; import 'package:clock_app/common/utils/list_storage.dart'; +import 'package:clock_app/common/widgets/fab.dart'; import 'package:clock_app/common/widgets/list/custom_list_view.dart'; import 'package:clock_app/developer/logic/logger.dart'; import 'package:clock_app/settings/types/listener_manager.dart'; @@ -78,7 +79,8 @@ class PersistentListView extends StatefulWidget { this.customActions = const [], this.sortOptions = const [], this.header, - this.onSaveItems , + this.onSaveItems, + this.bottomInset = 0, // this.initialSortIndex = 0, }); @@ -96,12 +98,13 @@ class PersistentListView extends StatefulWidget { final bool reloadOnPop; final bool isSelectable; final bool shouldInsertOnTop; - final Widget? header; + final Widget? header; // final int initialSortIndex; final List> listFilters; final List> customActions; final List> sortOptions; final Function(List items)? onSaveItems; + final double bottomInset; @override State createState() => _PersistentListViewState(); @@ -130,8 +133,7 @@ class _PersistentListViewState _initialSortIndex = int.parse(loadTextFileSync("${widget.saveTag}-sort-index")); } - } - else { + } else { _initialSortIndex = 0; } } @@ -139,7 +141,7 @@ class _PersistentListViewState @override void dispose() { ListenerManager.removeOnChangeListener(widget.saveTag, _loadItems); - + super.dispose(); } @@ -161,12 +163,11 @@ class _PersistentListViewState } } - void _saveItems () async { + void _saveItems() async { if (widget.saveTag.isNotEmpty) { await saveList(widget.saveTag, _items); } widget.onSaveItems?.call(_items); - } void _handleChangeSort(int index) { @@ -197,6 +198,7 @@ class _PersistentListViewState initialSortIndex: _initialSortIndex, onChangeSortIndex: _handleChangeSort, header: widget.header, + bottomInset: widget.bottomInset, ); } } diff --git a/lib/stopwatch/screens/stopwatch_screen.dart b/lib/stopwatch/screens/stopwatch_screen.dart index 2d17acea..7ed28625 100644 --- a/lib/stopwatch/screens/stopwatch_screen.dart +++ b/lib/stopwatch/screens/stopwatch_screen.dart @@ -166,6 +166,7 @@ class _StopwatchScreenState extends State { isDuplicateEnabled: false, isReorderable: false, onAddItem: (lap) => _stopwatch.updateFastestAndSlowestLap(), + bottomInset: FAB.bottomInset(context, size: 2), ), ), ], diff --git a/lib/timer/screens/timer_screen.dart b/lib/timer/screens/timer_screen.dart index 01b8f48b..cc772362 100644 --- a/lib/timer/screens/timer_screen.dart +++ b/lib/timer/screens/timer_screen.dart @@ -108,7 +108,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // } // } - class TimerScreen extends StatefulWidget { const TimerScreen({super.key, this.actionController}); @@ -410,6 +409,7 @@ class _TimerScreenState extends State { listFilters: _showFilters.value ? timerListFilters : [], sortOptions: _showSort.value ? timerSortOptions : [], customActions: _getCustomActions(), + bottomInset: FAB.bottomInset(context), ), ), ],