From 8d73a7d2e3593e27b15236c7fbfe254ff4faeb71 Mon Sep 17 00:00:00 2001 From: Vadim <44135514+vodemn@users.noreply.github.com> Date: Sun, 5 Feb 2023 17:20:36 +0300 Subject: [PATCH] ML-20 Dialog pickers content jumps when selected item is out of vie (#21) * fixed primary color picker overscroll * dialog cleanup * fixed photography value picker overscroll * Update widget_dialog_picker_photography_value.dart --- lib/providers/theme_provider.dart | 5 + lib/res/dimens.dart | 12 +++ ...idget_dialog_picker_photography_value.dart | 94 +++++++------------ .../widget_dialog_calibration.dart | 16 +--- .../widget_dialog_picker_primary_color.dart | 78 ++++++++------- .../widget_dialog_picker.dart | 14 +-- 6 files changed, 99 insertions(+), 120 deletions(-) diff --git a/lib/providers/theme_provider.dart b/lib/providers/theme_provider.dart index 70d008d..d2f1f37 100644 --- a/lib/providers/theme_provider.dart +++ b/lib/providers/theme_provider.dart @@ -208,6 +208,11 @@ class _ThemeDataProvider extends StatelessWidget { surfaceTintColor: scheme.surfaceTint, elevation: 6, ), + dividerColor: scheme.outlineVariant, + dividerTheme: DividerThemeData( + color: scheme.outlineVariant, + space: 0, + ), listTileTheme: ListTileThemeData( style: ListTileStyle.list, iconColor: scheme.onSurface, diff --git a/lib/res/dimens.dart b/lib/res/dimens.dart index 45756e2..79f5dc8 100644 --- a/lib/res/dimens.dart +++ b/lib/res/dimens.dart @@ -37,5 +37,17 @@ class Dimens { // Dialog // Taken from `Dialog` documentation + static const EdgeInsets dialogTitlePadding = EdgeInsets.fromLTRB( + paddingL, + paddingL, + paddingL, + paddingM, + ); + static const EdgeInsets dialogActionsPadding = EdgeInsets.fromLTRB( + paddingL, + paddingM, + paddingL, + paddingL, + ); static const EdgeInsets dialogMargin = EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0); } diff --git a/lib/screens/metering/components/shared/readings_container/components/animated_dialog_picker/components/photography_value_picker_dialog/widget_dialog_picker_photography_value.dart b/lib/screens/metering/components/shared/readings_container/components/animated_dialog_picker/components/photography_value_picker_dialog/widget_dialog_picker_photography_value.dart index 66cd15b..0d30042 100644 --- a/lib/screens/metering/components/shared/readings_container/components/animated_dialog_picker/components/photography_value_picker_dialog/widget_dialog_picker_photography_value.dart +++ b/lib/screens/metering/components/shared/readings_container/components/animated_dialog_picker/components/photography_value_picker_dialog/widget_dialog_picker_photography_value.dart @@ -36,15 +36,8 @@ class PhotographyValuePickerDialog extends StatefulW class _PhotographyValuePickerDialogState extends State> { late T _selectedValue = widget.initialValue; - final _scrollController = ScrollController(); - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { - _scrollController.jumpTo(Dimens.grid56 * widget.values.indexOf(_selectedValue)); - }); - } + late final _scrollController = + ScrollController(initialScrollOffset: Dimens.grid56 * widget.values.indexOf(_selectedValue)); @override void dispose() { @@ -57,35 +50,23 @@ class _PhotographyValuePickerDialogState return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Column( - children: [ - Padding( - padding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingM, + Padding( + padding: Dimens.dialogTitlePadding, + child: Column( + children: [ + Text( + widget.title, + style: Theme.of(context).textTheme.headlineSmall!, ), - child: Column( - children: [ - Text( - widget.title, - style: Theme.of(context).textTheme.headlineSmall!, - ), - const SizedBox(height: Dimens.grid16), - Text( - widget.subtitle, - style: Theme.of(context).textTheme.bodyMedium!, - ), - ], + const SizedBox(height: Dimens.grid16), + Text( + widget.subtitle, + style: Theme.of(context).textTheme.bodyMedium!, ), - ), - Divider( - color: Theme.of(context).colorScheme.onSurface, - height: 0, - ), - ], + ], + ), ), + const Divider(), Expanded( child: ListView.builder( controller: _scrollController, @@ -114,32 +95,25 @@ class _PhotographyValuePickerDialogState ), ), ), - Column( - children: [ - Divider( - color: Theme.of(context).colorScheme.onSurface, - height: 0, - ), - Padding( - padding: const EdgeInsets.all(Dimens.paddingL), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - const Spacer(), - TextButton( - onPressed: widget.onCancel, - child: Text(S.of(context).cancel), - ), - const SizedBox(width: Dimens.grid16), - TextButton( - onPressed: () => widget.onSelect(_selectedValue), - child: Text(S.of(context).select), - ), - ], + const Divider(), + Padding( + padding: Dimens.dialogActionsPadding, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + const Spacer(), + TextButton( + onPressed: widget.onCancel, + child: Text(S.of(context).cancel), ), - ), - ], + const SizedBox(width: Dimens.grid16), + TextButton( + onPressed: () => widget.onSelect(_selectedValue), + child: Text(S.of(context).select), + ), + ], + ), ), ], ); diff --git a/lib/screens/settings/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart b/lib/screens/settings/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart index 2b5c9b2..3af2bc0 100644 --- a/lib/screens/settings/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart +++ b/lib/screens/settings/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart @@ -3,11 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/res/dimens.dart'; -import 'package:lightmeter/screens/settings/components/calibration/components/calibration_dialog/event_dialog_calibration.dart'; import 'package:lightmeter/screens/shared/centered_slider/widget_slider_centered.dart'; import 'package:lightmeter/utils/to_string_signed.dart'; import 'bloc_dialog_calibration.dart'; +import 'event_dialog_calibration.dart'; import 'state_dialog_calibration.dart'; class CalibrationDialog extends StatelessWidget { @@ -17,12 +17,7 @@ class CalibrationDialog extends StatelessWidget { Widget build(BuildContext context) { final bool hasLightSensor = context.read().hasLightSensor; return AlertDialog( - titlePadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingM, - ), + titlePadding: Dimens.dialogTitlePadding, title: Text(S.of(context).calibration), contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL), content: SingleChildScrollView( @@ -67,12 +62,7 @@ class CalibrationDialog extends StatelessWidget { ], ), ), - actionsPadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingM, - Dimens.paddingL, - Dimens.paddingL, - ), + actionsPadding: Dimens.dialogActionsPadding, actions: [ TextButton( onPressed: Navigator.of(context).pop, diff --git a/lib/screens/settings/components/primary_color/components/primary_color_picker_dialog/widget_dialog_picker_primary_color.dart b/lib/screens/settings/components/primary_color/components/primary_color_picker_dialog/widget_dialog_picker_primary_color.dart index cab9007..40655b5 100644 --- a/lib/screens/settings/components/primary_color/components/primary_color_picker_dialog/widget_dialog_picker_primary_color.dart +++ b/lib/screens/settings/components/primary_color/components/primary_color_picker_dialog/widget_dialog_picker_primary_color.dart @@ -13,10 +13,7 @@ class PrimaryColorDialogPicker extends StatefulWidget { class _PrimaryColorDialogPickerState extends State { late Color _selected = Theme.of(context).primaryColor; - late final ScrollController _scrollController = ScrollController( - initialScrollOffset: - ThemeProvider.primaryColorsList.indexOf(_selected) * (Dimens.grid48 + Dimens.grid8), - ); + final ScrollController _scrollController = ScrollController(); @override void dispose() { @@ -27,42 +24,38 @@ class _PrimaryColorDialogPickerState extends State { @override Widget build(BuildContext context) { return AlertDialog( - titlePadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingM, - ), + titlePadding: Dimens.dialogTitlePadding, title: Text(S.of(context).choosePrimaryColor), content: SizedBox( height: Dimens.grid48, width: double.maxFinite, - child: ListView.separated( + child: SingleChildScrollView( controller: _scrollController, scrollDirection: Axis.horizontal, padding: EdgeInsets.zero, - separatorBuilder: (_, __) => const SizedBox(width: Dimens.grid8), - itemCount: ThemeProvider.primaryColorsList.length, - itemBuilder: (_, index) { - final color = ThemeProvider.primaryColorsList[index]; - return _SelectableColorItem( - color: color, - selected: color.value == _selected.value, - onTap: () { - setState(() { - _selected = color; - }); + child: Row( + children: List.generate( + ThemeProvider.primaryColorsList.length, + (index) { + final color = ThemeProvider.primaryColorsList[index]; + return Padding( + padding: EdgeInsets.only(left: index == 0 ? 0 : Dimens.paddingS), + child: _SelectableColorItem( + color: color, + selected: color.value == _selected.value, + onTap: () { + setState(() { + _selected = color; + }); + }, + ), + ); }, - ); - }, + ), + ), ), ), - actionsPadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingM, - Dimens.paddingL, - Dimens.paddingL, - ), + actionsPadding: Dimens.dialogActionsPadding, actions: [ TextButton( onPressed: Navigator.of(context).pop, @@ -79,7 +72,7 @@ class _PrimaryColorDialogPickerState extends State { } } -class _SelectableColorItem extends StatelessWidget { +class _SelectableColorItem extends StatefulWidget { final Color color; final bool selected; final VoidCallback onTap; @@ -90,19 +83,34 @@ class _SelectableColorItem extends StatelessWidget { required this.onTap, }) : super(key: ValueKey(color)); + @override + State<_SelectableColorItem> createState() => _SelectableColorItemState(); +} + +class _SelectableColorItemState extends State<_SelectableColorItem> { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (widget.selected) { + Scrollable.ensureVisible(context); + } + }); + } + @override Widget build(BuildContext context) { return GestureDetector( - onTap: onTap, + onTap: widget.onTap, child: FilledCircle( size: Dimens.grid48, - color: color, + color: widget.color, child: AnimatedSwitcher( duration: Dimens.durationS, - child: selected + child: widget.selected ? Icon( Icons.check, - color: ThemeData.estimateBrightnessForColor(color) == Brightness.light + color: ThemeData.estimateBrightnessForColor(widget.color) == Brightness.light ? Colors.black : Colors.white, ) diff --git a/lib/screens/settings/components/shared/dialog_picker.dart/widget_dialog_picker.dart b/lib/screens/settings/components/shared/dialog_picker.dart/widget_dialog_picker.dart index 03050ad..8044fb4 100644 --- a/lib/screens/settings/components/shared/dialog_picker.dart/widget_dialog_picker.dart +++ b/lib/screens/settings/components/shared/dialog_picker.dart/widget_dialog_picker.dart @@ -26,12 +26,7 @@ class _DialogPickerState extends State> { @override Widget build(BuildContext context) { return AlertDialog( - titlePadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingL, - Dimens.paddingM, - ), + titlePadding: Dimens.dialogTitlePadding, title: Text(widget.title), contentPadding: EdgeInsets.zero, content: Column( @@ -53,12 +48,7 @@ class _DialogPickerState extends State> { ) .toList(), ), - actionsPadding: const EdgeInsets.fromLTRB( - Dimens.paddingL, - Dimens.paddingM, - Dimens.paddingL, - Dimens.paddingL, - ), + actionsPadding: Dimens.dialogActionsPadding, actions: [ TextButton( onPressed: Navigator.of(context).pop,