mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-25 00:40:39 +00:00
added bottom widget to SliverScreen
This commit is contained in:
parent
756c179567
commit
3870dfeb28
2 changed files with 24 additions and 13 deletions
|
@ -1,15 +1,18 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/generated/l10n.dart';
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
|
import 'package:lightmeter/utils/text_height.dart';
|
||||||
|
|
||||||
class SliverScreen extends StatelessWidget {
|
class SliverScreen extends StatelessWidget {
|
||||||
final Widget title;
|
final Widget title;
|
||||||
final List<Widget> appBarActions;
|
final List<Widget> appBarActions;
|
||||||
|
final PreferredSizeWidget? bottom;
|
||||||
final List<Widget> slivers;
|
final List<Widget> slivers;
|
||||||
|
|
||||||
const SliverScreen({
|
const SliverScreen({
|
||||||
required this.title,
|
required this.title,
|
||||||
this.appBarActions = const [],
|
this.appBarActions = const [],
|
||||||
|
this.bottom,
|
||||||
required this.slivers,
|
required this.slivers,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
@ -24,7 +27,7 @@ class SliverScreen extends StatelessWidget {
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
SliverAppBar.large(
|
SliverAppBar.large(
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
expandedHeight: Dimens.sliverAppBarExpandedHeight,
|
expandedHeight: Dimens.sliverAppBarExpandedHeight + (bottom?.preferredSize.height ?? 0.0),
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
titlePadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
titlePadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
||||||
|
@ -37,10 +40,12 @@ class SliverScreen extends StatelessWidget {
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
child: _Title(
|
child: _Title(
|
||||||
actionsCount: appBarActions.length + (Navigator.of(context).canPop() ? 1 : 0),
|
actionsCount: appBarActions.length + (Navigator.of(context).canPop() ? 1 : 0),
|
||||||
|
bottomSize: bottom?.preferredSize.height ?? 0.0,
|
||||||
child: title,
|
child: title,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
bottom: bottom,
|
||||||
actions: [
|
actions: [
|
||||||
...appBarActions,
|
...appBarActions,
|
||||||
if (Navigator.of(context).canPop())
|
if (Navigator.of(context).canPop())
|
||||||
|
@ -62,35 +67,37 @@ class SliverScreen extends StatelessWidget {
|
||||||
class _Title extends StatelessWidget {
|
class _Title extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final int actionsCount;
|
final int actionsCount;
|
||||||
|
final double bottomSize;
|
||||||
final double actionsPadding;
|
final double actionsPadding;
|
||||||
|
|
||||||
const _Title({
|
const _Title({
|
||||||
required this.actionsCount,
|
required this.actionsCount,
|
||||||
|
required this.bottomSize,
|
||||||
required this.child,
|
required this.child,
|
||||||
}) : actionsPadding = Dimens.grid48 * actionsCount - Dimens.paddingM;
|
}) : actionsPadding = Dimens.grid48 * actionsCount - Dimens.paddingM;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>()!;
|
final settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>()!;
|
||||||
final titleScale = _titleScale(settings);
|
final extentScale =
|
||||||
|
((settings.maxExtent - settings.currentExtent) / (settings.maxExtent - settings.minExtent)).clamp(0.0, 1.0);
|
||||||
|
final titleScale = Tween<double>(begin: 1.5, end: 1.0).transform(extentScale);
|
||||||
final maxFromTextToAppbar = settings.maxExtent - settings.minExtent - Dimens.paddingM;
|
final maxFromTextToAppbar = settings.maxExtent - settings.minExtent - Dimens.paddingM;
|
||||||
final currentFromTextToAppbar = settings.currentExtent - settings.minExtent - Dimens.paddingM;
|
final currentFromTextToAppbar = settings.currentExtent - settings.minExtent - Dimens.paddingM;
|
||||||
final actionsPaddingScale = (1 - currentFromTextToAppbar / maxFromTextToAppbar).clamp(0.0, 1.0);
|
final actionsPaddingScale = (1 - currentFromTextToAppbar / maxFromTextToAppbar).clamp(0.0, 1.0);
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) => SizedBox(
|
builder: (context, constraints) => Padding(
|
||||||
height: settings.minExtent - MediaQuery.paddingOf(context).top,
|
padding: EdgeInsets.only(bottom: (Dimens.paddingM * (1 - actionsPaddingScale) + bottomSize) / titleScale),
|
||||||
width: constraints.maxWidth - (actionsPadding * actionsPaddingScale) / titleScale,
|
child: SizedBox(
|
||||||
child: Align(
|
height: DefaultTextStyle.of(context).style.lineHeight * 2,
|
||||||
alignment: Alignment.centerLeft,
|
width: constraints.maxWidth - (actionsPadding * actionsPaddingScale) / titleScale,
|
||||||
child: child,
|
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<double>(begin: 1.5, end: 1.0).transform(extentScale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,3 +34,7 @@ Size textSize(
|
||||||
)..layout(maxWidth: maxWidth);
|
)..layout(maxWidth: maxWidth);
|
||||||
return titlePainter.size;
|
return titlePainter.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension TextLineHeight on TextStyle {
|
||||||
|
double get lineHeight => fontSize! * height!;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue