Files
submanager/lib/widgets/glassmorphism_card.dart
JiWoong Sul 4731288622 Major UI/UX and architecture improvements
- Implemented new navigation system with NavigationProvider and route management
- Added adaptive theme system with ThemeProvider for better theme handling
- Introduced glassmorphism design elements (app bars, scaffolds, cards)
- Added advanced animations (spring animations, page transitions, staggered lists)
- Implemented performance optimizations (memory manager, lazy loading)
- Refactored Analysis screen into modular components
- Added floating navigation bar with haptic feedback
- Improved subscription cards with swipe actions
- Enhanced skeleton loading with better animations
- Added cached network image support
- Improved overall app architecture and code organization

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-10 18:36:57 +09:00

210 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'dart:ui';
import '../theme/app_colors.dart';
class GlassmorphismCard extends StatelessWidget {
final Widget child;
final EdgeInsetsGeometry? padding;
final EdgeInsetsGeometry? margin;
final double? width;
final double? height;
final double borderRadius;
final double blur;
final double opacity;
final Color? backgroundColor;
final Gradient? gradient;
final Border? border;
final List<BoxShadow>? boxShadow;
final VoidCallback? onTap;
const GlassmorphismCard({
super.key,
required this.child,
this.padding,
this.margin,
this.width,
this.height,
this.borderRadius = 16.0,
this.blur = 10.0,
this.opacity = 0.1,
this.backgroundColor,
this.gradient,
this.border,
this.boxShadow,
this.onTap,
});
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Container(
width: width,
height: height,
margin: margin,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(borderRadius),
child: ClipRRect(
borderRadius: BorderRadius.circular(borderRadius),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
child: Container(
padding: padding,
decoration: BoxDecoration(
color: backgroundColor ?? (isDarkMode
? AppColors.glassCardDark
: AppColors.glassCard),
gradient: gradient ?? LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: isDarkMode
? AppColors.glassGradientDark
: AppColors.glassGradient,
),
borderRadius: BorderRadius.circular(borderRadius),
border: border ?? Border.all(
color: isDarkMode
? AppColors.glassBorderDark
: AppColors.glassBorder,
width: 1.5,
),
boxShadow: boxShadow ?? [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 20,
spreadRadius: -5,
offset: const Offset(0, 10),
),
],
),
child: child,
),
),
),
),
),
);
}
}
// 애니메이션이 적용된 글래스모피즘 카드
class AnimatedGlassmorphismCard extends StatefulWidget {
final Widget child;
final EdgeInsetsGeometry? padding;
final EdgeInsetsGeometry? margin;
final double? width;
final double? height;
final double borderRadius;
final double blur;
final double opacity;
final Duration animationDuration;
final VoidCallback? onTap;
const AnimatedGlassmorphismCard({
super.key,
required this.child,
this.padding,
this.margin,
this.width,
this.height,
this.borderRadius = 16.0,
this.blur = 10.0,
this.opacity = 0.1,
this.animationDuration = const Duration(milliseconds: 200),
this.onTap,
});
@override
State<AnimatedGlassmorphismCard> createState() => _AnimatedGlassmorphismCardState();
}
class _AnimatedGlassmorphismCardState extends State<AnimatedGlassmorphismCard>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<double> _blurAnimation;
bool _isPressed = false;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.animationDuration,
vsync: this,
);
_scaleAnimation = Tween<double>(
begin: 1.0,
end: 0.98,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_blurAnimation = Tween<double>(
begin: widget.blur,
end: widget.blur * 1.5,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _handleTapDown(TapDownDetails details) {
setState(() {
_isPressed = true;
});
_controller.forward();
}
void _handleTapUp(TapUpDetails details) {
setState(() {
_isPressed = false;
});
_controller.reverse();
}
void _handleTapCancel() {
setState(() {
_isPressed = false;
});
_controller.reverse();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _handleTapDown,
onTapUp: _handleTapUp,
onTapCancel: _handleTapCancel,
onTap: widget.onTap,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.scale(
scale: _scaleAnimation.value,
child: GlassmorphismCard(
padding: widget.padding,
margin: widget.margin,
width: widget.width,
height: widget.height,
borderRadius: widget.borderRadius,
blur: _blurAnimation.value,
opacity: widget.opacity,
child: widget.child,
),
);
},
),
);
}
}