perf(ui): enable KeepAlive on subscription list, tune prefetch, and reduce list/gesture animations
This commit is contained in:
@@ -2,12 +2,14 @@ import 'package:flutter/material.dart';
|
||||
import '../models/subscription_model.dart';
|
||||
import '../utils/haptic_feedback_helper.dart';
|
||||
import 'subscription_card.dart';
|
||||
import '../utils/reduce_motion.dart';
|
||||
|
||||
class SwipeableSubscriptionCard extends StatefulWidget {
|
||||
final SubscriptionModel subscription;
|
||||
final VoidCallback? onEdit;
|
||||
final Future<void> Function()? onDelete;
|
||||
final VoidCallback? onTap;
|
||||
final bool keepAlive;
|
||||
|
||||
const SwipeableSubscriptionCard({
|
||||
super.key,
|
||||
@@ -15,6 +17,7 @@ class SwipeableSubscriptionCard extends StatefulWidget {
|
||||
this.onEdit,
|
||||
this.onDelete,
|
||||
this.onTap,
|
||||
this.keepAlive = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -23,7 +26,7 @@ class SwipeableSubscriptionCard extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
with SingleTickerProviderStateMixin {
|
||||
with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
// 상수 정의
|
||||
static const double _tapTolerance = 20.0; // 탭 허용 범위
|
||||
static const double _actionThresholdPercent = 0.15;
|
||||
@@ -49,7 +52,9 @@ class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
duration: ReduceMotion.platform()
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 300),
|
||||
vsync: this,
|
||||
);
|
||||
_animation = Tween<double>(
|
||||
@@ -215,10 +220,14 @@ class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
right: isLeft ? 0 : 24,
|
||||
),
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
duration: ReduceMotion.platform()
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 200),
|
||||
opacity: showIcon ? 1.0 : 0.0,
|
||||
child: AnimatedScale(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
duration: ReduceMotion.platform()
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 200),
|
||||
scale: showIcon ? 1.0 : 0.5,
|
||||
child: Icon(
|
||||
isDeleteThreshold
|
||||
@@ -236,9 +245,10 @@ class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
return Transform.translate(
|
||||
offset: Offset(_currentOffset, 0),
|
||||
child: Transform.scale(
|
||||
scale: 1.0 - (_currentOffset.abs() / 2000),
|
||||
scale:
|
||||
ReduceMotion.platform() ? 1.0 : 1.0 - (_currentOffset.abs() / 2000),
|
||||
child: Transform.rotate(
|
||||
angle: _currentOffset / 2000,
|
||||
angle: ReduceMotion.platform() ? 0.0 : _currentOffset / 2000,
|
||||
child: SubscriptionCard(
|
||||
subscription: widget.subscription,
|
||||
onTap: widget
|
||||
@@ -251,6 +261,7 @@ class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
// 웹과 모바일 모두 동일한 스와이프 기능 제공
|
||||
return Stack(
|
||||
children: [
|
||||
@@ -266,4 +277,7 @@ class _SwipeableSubscriptionCardState extends State<SwipeableSubscriptionCard>
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => widget.keepAlive;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user