Files
SpotiFLAC-Mobile/lib/screens/collapsing_header_scroll_mixin.dart
T
zarzet 44de61a06a refactor(screens): share album-screen scaffolding and track flows
- SelectionModeMixin + CollapsingHeaderScrollMixin extracted;
  local/downloaded album screens now share AlbumTrackTile,
  AlbumScaffoldBody, DestructiveSelectionButton, HeaderMetaRow,
  and confirmAndDeleteTracks
- track_detail_actions.dart: shared downloadSingleTrack,
  queueTracksSkippingDownloaded, download-all confirm, queued
  snackbar, release-date formatter, list footer, love-all
- TtlCache<T> replaces the copied 10-minute static caches;
  album fetch branches share _applyAlbumMetadata
- playlist error card now uses ErrorCard; formatMegabytes shared
  by queue tab and update dialog
2026-07-12 19:19:22 +07:00

37 lines
1.1 KiB
Dart

import 'package:flutter/material.dart';
/// 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) {
final mediaSize = MediaQuery.sizeOf(context);
return (mediaSize.height * 0.6).clamp(400.0, 580.0);
}
void _onHeaderScroll() {
final expandedHeight = calculateExpandedHeight(context);
final shouldShow =
scrollController.offset > (expandedHeight - kToolbarHeight - 20);
if (shouldShow != showTitleInAppBar) {
setState(() => showTitleInAppBar = shouldShow);
}
}
}