dreampad/lib/app/modules/home/widgets/explore_widget.dart

171 lines
5.3 KiB
Dart
Raw Permalink Normal View History

2023-11-28 10:44:58 +08:00
import 'package:dreampad/app/shared/shared.dart';
import 'package:flutter/material.dart';
2023-11-30 14:58:48 +08:00
import 'package:flutter_hooks/flutter_hooks.dart';
2023-11-28 10:44:58 +08:00
import 'package:flutter_screenutil/flutter_screenutil.dart';
2023-11-30 01:11:31 +08:00
class ExploreWidget extends StatefulWidget {
2023-11-28 10:44:58 +08:00
const ExploreWidget({
super.key,
required this.explored,
required this.exploreCount,
2023-11-30 01:11:31 +08:00
this.onPressed,
2023-11-30 14:58:48 +08:00
required this.remainTimePercent,
this.remainTimeStr,
2023-11-28 10:44:58 +08:00
});
2023-11-30 14:58:48 +08:00
2023-11-28 10:44:58 +08:00
final bool explored;
final int exploreCount;
2023-11-30 14:58:48 +08:00
final double remainTimePercent;
final String? remainTimeStr;
2023-11-30 01:11:31 +08:00
final VoidCallback? onPressed;
2023-11-30 14:58:48 +08:00
2023-11-30 01:11:31 +08:00
@override
State<ExploreWidget> createState() => _ExploreWidgetState();
}
2023-11-28 10:44:58 +08:00
2023-11-30 01:11:31 +08:00
class _ExploreWidgetState extends State<ExploreWidget> {
late bool suspend = false;
2023-11-30 14:58:48 +08:00
2023-11-28 10:44:58 +08:00
@override
Widget build(BuildContext context) {
2023-11-30 14:58:48 +08:00
return AnimatedSwitcher(
duration: kThemeAnimationDuration,
child: KeyedSubtree(
key: ValueKey(widget.explored),
child: Container(
height: 67.h,
width: 201.w,
decoration: BoxDecoration(
image: DecorationImage(
image: widget.explored
? Images.homeExplorePre
: Images.homeExploreDefault,
fit: BoxFit.fill,
),
2023-11-28 10:44:58 +08:00
),
2023-11-30 14:58:48 +08:00
child: Row(
2023-11-28 10:44:58 +08:00
children: [
2023-11-30 14:58:48 +08:00
const RSizedBox(width: 10.0),
GestureDetector(
onTap: () {
if (widget.explored) {
setState(() {
suspend = !suspend;
});
widget.onPressed?.call();
}
},
child: widget.explored
? _TimerCounter(
value: widget.remainTimePercent,
suspend: suspend,
)
: Images.homeBeginGray,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'自由探索',
style: widget.explored
? TextStyles.boldWhiteShadow22_101
: TextStyles.boldWhiteShadow22_100,
),
const RSizedBox(height: 4.0),
widget.explored
? Text(
'剩余时间:${widget.remainTimeStr}',
style: TextStyles.mediumWhiteShadow14_101,
)
: Row(
children: [
widget.exploreCount == 0
? Images.homeProgressBar
: Images.homeProgressBarIn,
const RSizedBox(width: 1.0),
widget.exploreCount >= 2
? Images.homeProgressBarIn
: Images.homeProgressBar,
],
),
],
2023-11-28 10:44:58 +08:00
),
],
),
2023-11-30 14:58:48 +08:00
),
),
);
}
}
class _TimerCounter extends StatelessWidget {
const _TimerCounter({
required this.value,
required this.suspend,
});
final double value;
final bool suspend;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 8),
child: SizedBox.square(
dimension: 45.h,
child: Stack(
children: [
Positioned.fill(
child: HookBuilder(
builder: (context) {
final animationController = useAnimationController(
duration: const Duration(seconds: 2),
);
useMemoized(() {
if (animationController.value < value) {
animationController.animateTo(value);
} else {
animationController.animateBack(value);
}
}, [value]);
return AnimatedBuilder(
animation: animationController,
builder: (context, _) => CircularProgressIndicator(
value: animationController.value,
color: Colors.white,
strokeWidth: 4,
backgroundColor: Colors.black.withOpacity(0.1),
),
);
}
),
),
Center(
child: HookBuilder(builder: (context) {
final animationController = useAnimationController(
duration: const Duration(milliseconds: 500),
initialValue: suspend ? 1.0 : 0.0
);
useMemoized(() {
if (suspend) {
animationController.forward();
} else {
animationController.reverse();
}
}, [suspend]);
return AnimatedIcon(
icon: AnimatedIcons.play_pause,
color: Colors.white,
progress: animationController,
);
}),
),
],
),
2023-11-28 10:44:58 +08:00
),
);
}
}