Files
flutter_common/lib/widget/year_selector.dart
2025-11-23 23:07:36 +08:00

127 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'common_widget.dart';
class YearSelector extends StatefulWidget {
final int currentYear;
final Function(int) onYearChanged;
const YearSelector(
{super.key, required this.currentYear, required this.onYearChanged});
@override
State<YearSelector> createState() => _YearSelectorState();
}
class _YearSelectorState extends State<YearSelector>
with SingleTickerProviderStateMixin {
final int minYear = 2000;
final int maxYear = 2100;
late int _currentYear;
// 用于动画效果
late AnimationController _animationController;
late Animation<double> _scaleAnimation;
@override
void initState() {
super.initState();
_currentYear = widget.currentYear;
// 初始化动画控制器
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
);
// 缩放动画
_scaleAnimation = Tween<double>(begin: 1.0, end: 1.1).animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
);
}
@override
void didUpdateWidget(YearSelector oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.currentYear != widget.currentYear) {
setState(() {
_currentYear = widget.currentYear;
});
}
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
/// 切换到上一年
void _previousYear() {
if (_currentYear > minYear) {
_animateYearChange(() {
final newYear = _currentYear - 1;
setState(() {
_currentYear = newYear;
});
widget.onYearChanged(newYear);
});
}
}
/// 切换到下一年
void _nextYear() {
if (_currentYear < maxYear) {
_animateYearChange(() {
final newYear = _currentYear + 1;
setState(() {
_currentYear = newYear;
});
widget.onYearChanged(newYear);
});
}
}
/// 年份变化时的动画效果
void _animateYearChange(VoidCallback onComplete) {
_animationController.forward().then((_) {
onComplete();
_animationController.reverse();
});
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleIconButton(
icon: Icons.chevron_left,
onPressed: _previousYear,
),
AnimatedBuilder(
animation: _scaleAnimation,
builder: (context, child) {
return Transform.scale(scale: _scaleAnimation.value, child: child);
},
child: Text(
'$_currentYear',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
),
CircleIconButton(
icon: Icons.chevron_right,
onPressed: _nextYear,
),
],
);
}
}