Files
SpotiFLAC-Mobile/lib/controllers/collapsing_header_scroll_mixin.dart
T
zarzet 99ccc8826f refactor(layering): move logic files out of screens
Search bucketing, refresh policy, folder data, history snapshot and the
selection and collapsing-header mixins hold no widgets, so they move to
controllers; the settings search catalog is pure presentation metadata and
moves to utils. Files with many importers keep a re-export in screens.
2026-10-19 00:37:42 +07:00

42 lines
1.3 KiB
Dart

import 'package:flutter/material.dart';
/// Expanded height of the album-style collapsing header, shared with the
/// loading screens that show the same header before the tracks arrive.
double collectionHeaderExpandedHeight(BuildContext context) {
final mediaSize = MediaQuery.sizeOf(context);
return (mediaSize.height * 0.6).clamp(400.0, 580.0);
}
/// Shared collapsing-header scroll behavior for album-style screens: owns the
/// [ScrollController] and flips [showTitleInAppBar] once the header has
/// scrolled out of view.
mixin CollapsingHeaderScrollMixin<T extends StatefulWidget> on State<T> {
final ScrollController scrollController = ScrollController();
bool showTitleInAppBar = false;
@override
void initState() {
super.initState();
scrollController.addListener(_onHeaderScroll);
}
@override
void dispose() {
scrollController.removeListener(_onHeaderScroll);
scrollController.dispose();
super.dispose();
}
double calculateExpandedHeight(BuildContext context) =>
collectionHeaderExpandedHeight(context);
void _onHeaderScroll() {
final expandedHeight = calculateExpandedHeight(context);
final shouldShow =
scrollController.offset > (expandedHeight - kToolbarHeight - 20);
if (shouldShow != showTitleInAppBar) {
setState(() => showTitleInAppBar = shouldShow);
}
}
}