mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 23:10:40 +00:00
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
This commit is contained in:
parent
9436a59094
commit
8d73a7d2e3
6 changed files with 99 additions and 120 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -36,15 +36,8 @@ class PhotographyValuePickerDialog<T extends PhotographyValue> extends StatefulW
|
|||
class _PhotographyValuePickerDialogState<T extends PhotographyValue>
|
||||
extends State<PhotographyValuePickerDialog<T>> {
|
||||
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<T extends PhotographyValue>
|
|||
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<T extends PhotographyValue>
|
|||
),
|
||||
),
|
||||
),
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -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<Environment>().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,
|
||||
|
|
|
@ -13,10 +13,7 @@ class PrimaryColorDialogPicker extends StatefulWidget {
|
|||
|
||||
class _PrimaryColorDialogPickerState extends State<PrimaryColorDialogPicker> {
|
||||
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<PrimaryColorDialogPicker> {
|
|||
@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<PrimaryColorDialogPicker> {
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
)
|
||||
|
|
|
@ -26,12 +26,7 @@ class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
|||
@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<T> extends State<DialogPicker<T>> {
|
|||
)
|
||||
.toList(),
|
||||
),
|
||||
actionsPadding: const EdgeInsets.fromLTRB(
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingM,
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingL,
|
||||
),
|
||||
actionsPadding: Dimens.dialogActionsPadding,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
|
|
Loading…
Reference in a new issue