diff --git a/lib/screens/shared/sliver_screen/screen_sliver.dart b/lib/screens/shared/sliver_screen/screen_sliver.dart index b4ae69d..a0de0e4 100644 --- a/lib/screens/shared/sliver_screen/screen_sliver.dart +++ b/lib/screens/shared/sliver_screen/screen_sliver.dart @@ -1,15 +1,18 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/res/dimens.dart'; +import 'package:lightmeter/utils/text_height.dart'; class SliverScreen extends StatelessWidget { final Widget title; final List appBarActions; + final PreferredSizeWidget? bottom; final List slivers; const SliverScreen({ required this.title, this.appBarActions = const [], + this.bottom, required this.slivers, super.key, }); @@ -24,7 +27,7 @@ class SliverScreen extends StatelessWidget { slivers: [ SliverAppBar.large( automaticallyImplyLeading: false, - expandedHeight: Dimens.sliverAppBarExpandedHeight, + expandedHeight: Dimens.sliverAppBarExpandedHeight + (bottom?.preferredSize.height ?? 0.0), flexibleSpace: FlexibleSpaceBar( centerTitle: false, titlePadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM), @@ -37,10 +40,12 @@ class SliverScreen extends StatelessWidget { overflow: TextOverflow.ellipsis, child: _Title( actionsCount: appBarActions.length + (Navigator.of(context).canPop() ? 1 : 0), + bottomSize: bottom?.preferredSize.height ?? 0.0, child: title, ), ), ), + bottom: bottom, actions: [ ...appBarActions, if (Navigator.of(context).canPop()) @@ -62,35 +67,37 @@ class SliverScreen extends StatelessWidget { class _Title extends StatelessWidget { final Widget child; final int actionsCount; + final double bottomSize; final double actionsPadding; const _Title({ required this.actionsCount, + required this.bottomSize, required this.child, }) : actionsPadding = Dimens.grid48 * actionsCount - Dimens.paddingM; @override Widget build(BuildContext context) { final settings = context.dependOnInheritedWidgetOfExactType()!; - final titleScale = _titleScale(settings); + final extentScale = + ((settings.maxExtent - settings.currentExtent) / (settings.maxExtent - settings.minExtent)).clamp(0.0, 1.0); + final titleScale = Tween(begin: 1.5, end: 1.0).transform(extentScale); final maxFromTextToAppbar = settings.maxExtent - settings.minExtent - Dimens.paddingM; final currentFromTextToAppbar = settings.currentExtent - settings.minExtent - Dimens.paddingM; final actionsPaddingScale = (1 - currentFromTextToAppbar / maxFromTextToAppbar).clamp(0.0, 1.0); return LayoutBuilder( - builder: (context, constraints) => SizedBox( - height: settings.minExtent - MediaQuery.paddingOf(context).top, - width: constraints.maxWidth - (actionsPadding * actionsPaddingScale) / titleScale, - child: Align( - alignment: Alignment.centerLeft, - child: child, + builder: (context, constraints) => Padding( + padding: EdgeInsets.only(bottom: (Dimens.paddingM * (1 - actionsPaddingScale) + bottomSize) / titleScale), + child: SizedBox( + height: DefaultTextStyle.of(context).style.lineHeight * 2, + width: constraints.maxWidth - (actionsPadding * actionsPaddingScale) / titleScale, + child: Align( + alignment: FractionalOffset(0.0, 0.5 + 0.5 * (1 - extentScale)), + child: child, + ), ), ), ); } - - double _titleScale(FlexibleSpaceBarSettings s) { - final extentScale = ((s.maxExtent - s.currentExtent) / (s.maxExtent - s.minExtent)).clamp(0.0, 1.0); - return Tween(begin: 1.5, end: 1.0).transform(extentScale); - } } diff --git a/lib/utils/text_height.dart b/lib/utils/text_height.dart index 6c3afa4..3c0faee 100644 --- a/lib/utils/text_height.dart +++ b/lib/utils/text_height.dart @@ -34,3 +34,7 @@ Size textSize( )..layout(maxWidth: maxWidth); return titlePainter.size; } + +extension TextLineHeight on TextStyle { + double get lineHeight => fontSize! * height!; +}