fix: 플로팅 네비게이션 바 렌더링 문제 해결
- SMS 화면에서 그림자가 제대로 표시되지 않던 문제 수정 - Stack 구조를 Container로 단순화하여 렌더링 최적화 - RenderFlex overflow 오류 해결 (패딩 및 아이콘 크기 조정) - Android 패키지명 변경 및 빌드 설정 업데이트
This commit is contained in:
@@ -20,16 +20,20 @@ import 'navigation/app_navigation_observer.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
import 'dart:io' show Platform;
|
||||
import 'dart:async' show unawaited;
|
||||
import 'utils/memory_manager.dart';
|
||||
import 'utils/performance_optimizer.dart';
|
||||
import 'navigator_key.dart';
|
||||
|
||||
// AdMob 활성화 플래그 (개발 중 false, 프로덕션 시 true로 변경)
|
||||
const bool enableAdMob = false;
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// 구글 모바일 광고 SDK 초기화 (웹이 아니고, Android/iOS에서만)
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
await MobileAds.instance.initialize();
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS) && enableAdMob) {
|
||||
unawaited(MobileAds.instance.initialize());
|
||||
}
|
||||
|
||||
// 성능 최적화 설정
|
||||
|
||||
@@ -25,7 +25,7 @@ class AdaptiveTheme {
|
||||
|
||||
scaffoldBackgroundColor: const Color(0xFF121212),
|
||||
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
color: const Color(0xFF1E1E1E),
|
||||
elevation: 2,
|
||||
shadowColor: Colors.black.withValues(alpha: 0.3),
|
||||
@@ -235,7 +235,7 @@ class AdaptiveTheme {
|
||||
),
|
||||
),
|
||||
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -18,7 +18,7 @@ class AppTheme {
|
||||
scaffoldBackgroundColor: AppColors.backgroundColor,
|
||||
|
||||
// 카드 스타일 - 글래스모피즘 효과
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
color: AppColors.glassCard,
|
||||
elevation: 0,
|
||||
shadowColor: AppColors.shadowBlack,
|
||||
@@ -307,7 +307,7 @@ class AppTheme {
|
||||
),
|
||||
|
||||
// 탭바 스타일
|
||||
tabBarTheme: const TabBarTheme(
|
||||
tabBarTheme: const TabBarThemeData(
|
||||
labelColor: AppColors.primaryColor,
|
||||
unselectedLabelColor: AppColors.textSecondary,
|
||||
indicatorColor: AppColors.primaryColor,
|
||||
|
||||
@@ -75,66 +75,61 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar>
|
||||
offset: Offset(0, 100 * (1 - _animation.value)),
|
||||
child: Opacity(
|
||||
opacity: _animation.value,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 흰색 배경 레이어 (완전 불투명)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.surfaceColor,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: AppColors.shadowBlack,
|
||||
blurRadius: 20,
|
||||
spreadRadius: -5,
|
||||
offset: Offset(0, 10),
|
||||
),
|
||||
],
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(4), // 그림자 공간 확보
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.surfaceColor,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: AppColors.shadowBlack,
|
||||
blurRadius: 12,
|
||||
spreadRadius: 0,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: GlassmorphismCard(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
borderRadius: 24,
|
||||
blur: 10.0,
|
||||
backgroundColor: Colors.transparent,
|
||||
boxShadow: const [], // 그림자는 Container에서 처리
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_NavigationItem(
|
||||
icon: Icons.home_rounded,
|
||||
label: AppLocalizations.of(context).home,
|
||||
isSelected: widget.selectedIndex == 0,
|
||||
onTap: () => _onItemTapped(0),
|
||||
),
|
||||
_NavigationItem(
|
||||
icon: Icons.analytics_rounded,
|
||||
label: AppLocalizations.of(context).analysis,
|
||||
isSelected: widget.selectedIndex == 1,
|
||||
onTap: () => _onItemTapped(1),
|
||||
),
|
||||
_AddButton(
|
||||
onTap: () => _onItemTapped(2),
|
||||
),
|
||||
if (!PlatformHelper.isIOS)
|
||||
_NavigationItem(
|
||||
icon: Icons.qr_code_scanner_rounded,
|
||||
label: AppLocalizations.of(context).smsScanLabel,
|
||||
isSelected: widget.selectedIndex == 3,
|
||||
onTap: () => _onItemTapped(3),
|
||||
),
|
||||
_NavigationItem(
|
||||
icon: Icons.settings_rounded,
|
||||
label: AppLocalizations.of(context).settings,
|
||||
isSelected: PlatformHelper.isIOS ? widget.selectedIndex == 3 : widget.selectedIndex == 4,
|
||||
onTap: () => _onItemTapped(PlatformHelper.isIOS ? 3 : 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
// 글래스모피즘 레이어 (시각적 효과)
|
||||
GlassmorphismCard(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
borderRadius: 24,
|
||||
blur: 10.0,
|
||||
backgroundColor: Colors.transparent,
|
||||
boxShadow: const [], // 그림자는 배경 레이어에서 처리
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_NavigationItem(
|
||||
icon: Icons.home_rounded,
|
||||
label: AppLocalizations.of(context).home,
|
||||
isSelected: widget.selectedIndex == 0,
|
||||
onTap: () => _onItemTapped(0),
|
||||
),
|
||||
_NavigationItem(
|
||||
icon: Icons.analytics_rounded,
|
||||
label: AppLocalizations.of(context).analysis,
|
||||
isSelected: widget.selectedIndex == 1,
|
||||
onTap: () => _onItemTapped(1),
|
||||
),
|
||||
_AddButton(
|
||||
onTap: () => _onItemTapped(2),
|
||||
),
|
||||
if (!PlatformHelper.isIOS)
|
||||
_NavigationItem(
|
||||
icon: Icons.qr_code_scanner_rounded,
|
||||
label: AppLocalizations.of(context).smsScanLabel,
|
||||
isSelected: widget.selectedIndex == 3,
|
||||
onTap: () => _onItemTapped(3),
|
||||
),
|
||||
_NavigationItem(
|
||||
icon: Icons.settings_rounded,
|
||||
label: AppLocalizations.of(context).settings,
|
||||
isSelected: PlatformHelper.isIOS ? widget.selectedIndex == 3 : widget.selectedIndex == 4,
|
||||
onTap: () => _onItemTapped(PlatformHelper.isIOS ? 3 : 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -169,7 +164,7 @@ class _NavigationItem extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? AppColors.primaryColor.withValues(alpha: 0.1)
|
||||
@@ -184,14 +179,14 @@ class _NavigationItem extends StatelessWidget {
|
||||
child: Icon(
|
||||
icon,
|
||||
color: isSelected ? AppColors.primaryColor : AppColors.navyGray,
|
||||
size: isSelected ? 26 : 24,
|
||||
size: isSelected ? 24 : 22,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
const SizedBox(height: 2),
|
||||
AnimatedDefaultTextStyle(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontSize: 10,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500,
|
||||
color: isSelected ? AppColors.primaryColor : AppColors.navyGray,
|
||||
),
|
||||
|
||||
@@ -153,15 +153,14 @@ class _GlassmorphicScaffoldState extends State<GlassmorphicScaffold>
|
||||
Widget _buildBackground(List<Color> gradientColors) {
|
||||
return Positioned.fill(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
AppColors.backgroundColor,
|
||||
...gradientColors.map((color) => color.withValues(alpha: 0.05)).toList(),
|
||||
AppColors.backgroundColor,
|
||||
],
|
||||
color: AppColors.backgroundColor, // 베이스 색상 추가
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: gradientColors.map((color) => color.withOpacity(0.3)).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'dart:io' show Platform;
|
||||
import 'glassmorphism_card.dart';
|
||||
import '../main.dart' show enableAdMob;
|
||||
|
||||
/// 구글 네이티브 광고 위젯 (AdMob NativeAd)
|
||||
/// SRP에 따라 광고 전용 위젯으로 분리
|
||||
@@ -162,6 +163,11 @@ class _NativeAdWidgetState extends State<NativeAdWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// AdMob이 비활성화된 경우 빈 컨테이너 반환
|
||||
if (!enableAdMob) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
// 웹 환경인 경우 플레이스홀더 표시
|
||||
if (kIsWeb) {
|
||||
return _buildWebPlaceholder();
|
||||
|
||||
Reference in New Issue
Block a user