Files
ReelShort/lib/pages/player/widgets/loading_progress_track.dart

103 lines
2.9 KiB
Dart

// Author: fruit.com.cn
import 'package:flutter/material.dart';
import '../../../core/theme/app_colors.dart';
/// 播放未就绪时沿进度轨道循环移动的加载高光。
class LoadingProgressTrack extends StatefulWidget {
const LoadingProgressTrack({
super.key = const Key('progress-loading'),
required this.height,
this.trackColor = AppColors.inactiveTrack,
this.highlightColor = AppColors.onPrimary,
});
final double height;
final Color trackColor;
final Color highlightColor;
@override
State<LoadingProgressTrack> createState() => _LoadingProgressTrackState();
}
class _LoadingProgressTrackState extends State<LoadingProgressTrack>
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
late final AnimationController _controller;
late final Animation<double> _position;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
);
_position = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
WidgetsBinding.instance.addObserver(this);
_syncAnimation();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
_syncAnimation();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_controller.dispose();
super.dispose();
}
void _syncAnimation() {
if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) {
if (!_controller.isAnimating) _controller.repeat();
} else {
_controller.stop();
}
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: widget.height,
child: ClipRRect(
borderRadius: BorderRadius.circular(widget.height / 2),
child: LayoutBuilder(
builder: (context, constraints) {
final highlightWidth = constraints.maxWidth * 0.28;
final travel = constraints.maxWidth + highlightWidth;
return AnimatedBuilder(
animation: _position,
builder: (context, _) {
final left = -highlightWidth + travel * _position.value;
return Stack(
fit: StackFit.expand,
children: [
ColoredBox(
key: const Key('progress-loading-track'),
color: widget.trackColor,
),
Positioned(
left: left,
top: 0,
bottom: 0,
width: highlightWidth,
child: ColoredBox(
key: const Key('progress-loading-highlight'),
color: widget.highlightColor,
),
),
],
);
},
);
},
),
),
);
}
}