11 KiB
🌐 سیستم تغییر زبان در اپلیکیشن LBA
📋 فهرست مطالب
- معرفی کلی
- ساختار فایلها
- زبانهای پشتیبانی شده
- کامپوننتهای کلیدی
- نحوه پیادهسازی
- مدیریت State
- UI/UX طراحی
- نکات فنی
- استفاده در صفحات مختلف
- عیبیابی
🎯 معرفی کلی
سیستم تغییر زبان در اپ LBA امکان انتخاب بین سه زبان انگلیسی، عربی و فارسی را فراهم میکند. این سیستم در دو صفحه اصلی قابل دسترسی است:
- صفحه Onboarding (بالای راست)
- صفحه Profile (بخش تنظیمات)
📁 ساختار فایلها
lib/
├── widgets/
│ └── language_selection_dialog.dart # کامپوننت اصلی انتخاب زبان
├── screens/
│ ├── auth/
│ │ └── onboarding_page.dart # صفحه معرفی با انتخاب زبان
│ └── mains/profile/
│ └── profile.dart # صفحه پروفایل
├── gen/
│ └── assets.gen.dart # فایلهای asset تولید شده
└── res/
└── colors.dart # رنگهای اپلیکیشن
🌍 زبانهای پشتیبانی شده
| زبان | کد | پرچم | فایل آیکون |
|---|---|---|---|
| English | en |
🇺🇲 | assets/icons/usa circle.svg |
| العربية | ar |
🇦🇪 | assets/icons/arab circle.svg |
| فارسی | fa |
🇮🇷 | assets/icons/iran circle.svg |
🔧 کامپوننتهای کلیدی
1. LanguageSelectionOverlay
کامپوننت اصلی که overlay انتخاب زبان را نمایش میدهد.
پراپهای ورودی:
final String currentLanguage; // زبان فعلی
final Function(String language, String flag) onLanguageSelected; // کالبک انتخاب
final GlobalKey targetKey; // کلید موقعیتیابی
2. showLanguageSelectionOverlay
تابع کمکی برای نمایش overlay:
void showLanguageSelectionOverlay(
BuildContext context,
String currentLanguage,
Function(String language, String flag) onLanguageSelected,
GlobalKey targetKey,
)
🛠 نحوه پیادهسازی
مرحله 1: اضافه کردن State متغیرها
class _YourPageState extends State<YourPage> {
String _currentLanguage = '🇺🇲 English';
String _currentFlag = 'assets/icons/usa circle.svg';
final GlobalKey _languageKey = GlobalKey();
// ... سایر کدها
}
مرحله 2: ایجاد UI انتخاب زبان
GestureDetector(
key: _languageKey,
onTap: () {
showLanguageSelectionOverlay(
context,
_currentLanguage,
(language, flag) {
setState(() {
_currentLanguage = language;
_currentFlag = flag;
});
},
_languageKey,
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// نمایش پرچم
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: ClipRRect(
key: ValueKey(_currentFlag),
borderRadius: BorderRadius.circular(4),
child: SvgPicture.asset(
_currentFlag,
width: 24,
height: 18,
),
),
),
const SizedBox(width: 8),
// نمایش نام زبان
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: Text(
_currentLanguage,
key: ValueKey(_currentLanguage),
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
color: AppColors.textPrimary,
),
),
),
const SizedBox(width: 8),
// آیکون فلش
SvgPicture.asset(
Assets.icons.arrowRight.path,
color: AppColors.textPrimary,
),
],
),
),
مرحله 3: اضافه کردن Import ها
import 'package:flutter_svg/flutter_svg.dart';
import '../../widgets/language_selection_dialog.dart';
import '../../gen/assets.gen.dart';
import '../../res/colors.dart';
🔄 مدیریت State
Local State Management
هر صفحه state زبان خود را بهصورت جداگانه مدیریت میکند:
// متغیرهای state
String _currentLanguage = '🇺🇲 English'; // نام کامل زبان با پرچم
String _currentFlag = 'assets/icons/usa circle.svg'; // مسیر فایل پرچم
// تابع تغییر زبان
void _changeLanguage(String language, String flag) {
setState(() {
_currentLanguage = language;
_currentFlag = flag;
});
}
Persistence (در آینده)
برای ذخیره انتخاب زبان کاربر میتوان از SharedPreferences استفاده کرد:
// ذخیره زبان
Future<void> _saveLanguage(String languageCode) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('selected_language', languageCode);
}
// بازیابی زبان
Future<String> _loadLanguage() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('selected_language') ?? 'en';
}
🎨 UI/UX طراحی
Positioning Logic
سیستم positioning هوشمند برای مکانیابی overlay:
// تشخیص موقعیت target در صفحه
if (targetPosition.dx > screenWidth * 0.7) {
// انتهای راست (مثل onboarding)
rightPosition = 16;
} else {
// وسط یا چپ (مثل profile)
rightPosition = 24;
}
Animation ها
- Scale Animation: ورود overlay با افکت scale
- Opacity Animation: fade in/out
- Switcher Animation: تغییر پرچم و متن با
AnimatedSwitcher
AnimationController _animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);
Animation<double> _scaleAnimation = Tween<double>(
begin: 0.8,
end: 1.0
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeOutBack
));
طراحی Overlay
Container(
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16),
topLeft: Radius.circular(16),
),
boxShadow: [
BoxShadow(
color: AppColors.shadowColor,
blurRadius: 15,
spreadRadius: 3,
offset: const Offset(0, 5),
),
],
),
// محتوای overlay
)
⚡ نکات فنی
1. Error Handling
برای مواردی که asset پرچم بارگذاری نشود:
errorBuilder: (context, error, stackTrace) {
return Container(
width: 24,
height: 18,
decoration: BoxDecoration(
color: AppColors.greyBorder.withOpacity(0.2),
borderRadius: BorderRadius.circular(4),
),
child: Icon(
Icons.flag,
color: AppColors.textSecondary,
size: 12,
),
);
}
2. Responsive Design
سیستم با اندازههای مختلف صفحه سازگار است:
final overlayWidth = screenWidth * 0.45; // 45% عرض صفحه
3. RTL Support
پشتیبانی از زبانهای راست به چپ:
textDirection: (code == 'ar' || code == 'fa')
? TextDirection.rtl
: TextDirection.ltr,
4. Performance
استفاده از ValueKey برای بهینهسازی rebuilds:
AnimatedSwitcher(
child: Widget(
key: ValueKey(_currentLanguage), // جلوگیری از rebuild غیرضروری
// ...
),
)
📱 استفاده در صفحات مختلف
صفحه Onboarding
// موقعیت: بالای راست صفحه
Container(
padding: EdgeInsets.fromLTRB(width/15, height/20, width/15, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// دکمه Skip
GestureDetector(onTap: _skipOnboarding, child: Text('Skip')),
// انتخاب زبان
LanguageSelector(),
],
),
)
صفحه Profile
// موقعیت: در بخش General Settings
_buildInfoTile(
icon: SvgPicture.asset(Assets.icons.languageSquare.path),
title: 'Language',
trailing: LanguageSelector(),
),
🔍 عیبیابی
مشکلات متداول
1. Overlay خارج از صفحه
علت: positioning غلط
راهحل: بررسی محاسبات leftPosition و rightPosition
// اطمینان از عدم overflow
if (leftPosition + overlayWidth > screenWidth - 16) {
leftPosition = screenWidth - overlayWidth - 16;
}
2. Asset پرچم نمایش داده نمیشود
علت: مسیر فایل اشتباه
راهحل: بررسی assets.gen.dart و مسیرهای فایل
// بررسی وجود فایل
child: _currentFlag.endsWith('.svg')
? SvgPicture.asset(_currentFlag)
: Image.asset(_currentFlag),
3. Animation کار نمیکند
علت: AnimationController dispose نشده
راهحل:
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
Debug Commands
// برای debug positioning
print('Target position: ${targetPosition.dx}, ${targetPosition.dy}');
print('Screen width: $screenWidth');
print('Overlay width: $overlayWidth');
🚀 بهبودهای آینده
1. Localization Integration
// اتصال به سیستم i18n Flutter
class LocalizationManager {
static void changeLocale(BuildContext context, String languageCode) {
// تغییر زبان کل اپ
}
}
2. Theme Integration
// تغییر زبان همراه با تغییر direction
void _changeLanguage(String code) {
final isRTL = ['ar', 'fa'].contains(code);
// اعمال تغییرات theme
}
3. Network Integration
// دریافت متنها از سرور
class LanguageService {
Future<Map<String, String>> getTranslations(String languageCode) {
// API call
}
}
📞 پشتیبانی
برای مشکلات فنی یا پیشنهادات بهبود، با تیم توسعه تماس بگیرید.
نسخه مستندات: 1.0
آخرین بروزرسانی: 22 سپتامبر 2025
نگارنده: GitHub Copilot
این مستندات برای توسعهدهندگان اپلیکیشن LBA تهیه شده است.