439 lines
11 KiB
Markdown
439 lines
11 KiB
Markdown
# 🌐 سیستم تغییر زبان در اپلیکیشن LBA
|
||
|
||
## 📋 فهرست مطالب
|
||
1. [معرفی کلی](#معرفی-کلی)
|
||
2. [ساختار فایلها](#ساختار-فایلها)
|
||
3. [زبانهای پشتیبانی شده](#زبانهای-پشتیبانی-شده)
|
||
4. [کامپوننتهای کلیدی](#کامپوننتهای-کلیدی)
|
||
5. [نحوه پیادهسازی](#نحوه-پیادهسازی)
|
||
6. [مدیریت State](#مدیریت-state)
|
||
7. [UI/UX طراحی](#uiux-طراحی)
|
||
8. [نکات فنی](#نکات-فنی)
|
||
9. [استفاده در صفحات مختلف](#استفاده-در-صفحات-مختلف)
|
||
10. [عیبیابی](#عیبیابی)
|
||
|
||
---
|
||
|
||
## 🎯 معرفی کلی
|
||
|
||
سیستم تغییر زبان در اپ 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 انتخاب زبان را نمایش میدهد.
|
||
|
||
**پراپهای ورودی:**
|
||
```dart
|
||
final String currentLanguage; // زبان فعلی
|
||
final Function(String language, String flag) onLanguageSelected; // کالبک انتخاب
|
||
final GlobalKey targetKey; // کلید موقعیتیابی
|
||
```
|
||
|
||
### 2. `showLanguageSelectionOverlay`
|
||
تابع کمکی برای نمایش overlay:
|
||
|
||
```dart
|
||
void showLanguageSelectionOverlay(
|
||
BuildContext context,
|
||
String currentLanguage,
|
||
Function(String language, String flag) onLanguageSelected,
|
||
GlobalKey targetKey,
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠 نحوه پیادهسازی
|
||
|
||
### مرحله 1: اضافه کردن State متغیرها
|
||
|
||
```dart
|
||
class _YourPageState extends State<YourPage> {
|
||
String _currentLanguage = '🇺🇲 English';
|
||
String _currentFlag = 'assets/icons/usa circle.svg';
|
||
final GlobalKey _languageKey = GlobalKey();
|
||
|
||
// ... سایر کدها
|
||
}
|
||
```
|
||
|
||
### مرحله 2: ایجاد UI انتخاب زبان
|
||
|
||
```dart
|
||
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 ها
|
||
|
||
```dart
|
||
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 زبان خود را بهصورت جداگانه مدیریت میکند:
|
||
|
||
```dart
|
||
// متغیرهای state
|
||
String _currentLanguage = '🇺🇲 English'; // نام کامل زبان با پرچم
|
||
String _currentFlag = 'assets/icons/usa circle.svg'; // مسیر فایل پرچم
|
||
|
||
// تابع تغییر زبان
|
||
void _changeLanguage(String language, String flag) {
|
||
setState(() {
|
||
_currentLanguage = language;
|
||
_currentFlag = flag;
|
||
});
|
||
}
|
||
```
|
||
|
||
### Persistence (در آینده)
|
||
برای ذخیره انتخاب زبان کاربر میتوان از `SharedPreferences` استفاده کرد:
|
||
|
||
```dart
|
||
// ذخیره زبان
|
||
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:
|
||
|
||
```dart
|
||
// تشخیص موقعیت 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`
|
||
|
||
```dart
|
||
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
|
||
|
||
```dart
|
||
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 پرچم بارگذاری نشود:
|
||
|
||
```dart
|
||
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
|
||
سیستم با اندازههای مختلف صفحه سازگار است:
|
||
|
||
```dart
|
||
final overlayWidth = screenWidth * 0.45; // 45% عرض صفحه
|
||
```
|
||
|
||
### 3. RTL Support
|
||
پشتیبانی از زبانهای راست به چپ:
|
||
|
||
```dart
|
||
textDirection: (code == 'ar' || code == 'fa')
|
||
? TextDirection.rtl
|
||
: TextDirection.ltr,
|
||
```
|
||
|
||
### 4. Performance
|
||
استفاده از `ValueKey` برای بهینهسازی rebuilds:
|
||
|
||
```dart
|
||
AnimatedSwitcher(
|
||
child: Widget(
|
||
key: ValueKey(_currentLanguage), // جلوگیری از rebuild غیرضروری
|
||
// ...
|
||
),
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 📱 استفاده در صفحات مختلف
|
||
|
||
### صفحه Onboarding
|
||
```dart
|
||
// موقعیت: بالای راست صفحه
|
||
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
|
||
```dart
|
||
// موقعیت: در بخش General Settings
|
||
_buildInfoTile(
|
||
icon: SvgPicture.asset(Assets.icons.languageSquare.path),
|
||
title: 'Language',
|
||
trailing: LanguageSelector(),
|
||
),
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 عیبیابی
|
||
|
||
### مشکلات متداول
|
||
|
||
#### 1. Overlay خارج از صفحه
|
||
**علت**: positioning غلط
|
||
**راهحل**: بررسی محاسبات `leftPosition` و `rightPosition`
|
||
|
||
```dart
|
||
// اطمینان از عدم overflow
|
||
if (leftPosition + overlayWidth > screenWidth - 16) {
|
||
leftPosition = screenWidth - overlayWidth - 16;
|
||
}
|
||
```
|
||
|
||
#### 2. Asset پرچم نمایش داده نمیشود
|
||
**علت**: مسیر فایل اشتباه
|
||
**راهحل**: بررسی `assets.gen.dart` و مسیرهای فایل
|
||
|
||
```dart
|
||
// بررسی وجود فایل
|
||
child: _currentFlag.endsWith('.svg')
|
||
? SvgPicture.asset(_currentFlag)
|
||
: Image.asset(_currentFlag),
|
||
```
|
||
|
||
#### 3. Animation کار نمیکند
|
||
**علت**: `AnimationController` dispose نشده
|
||
**راهحل**:
|
||
|
||
```dart
|
||
@override
|
||
void dispose() {
|
||
_animationController.dispose();
|
||
super.dispose();
|
||
}
|
||
```
|
||
|
||
### Debug Commands
|
||
```dart
|
||
// برای debug positioning
|
||
print('Target position: ${targetPosition.dx}, ${targetPosition.dy}');
|
||
print('Screen width: $screenWidth');
|
||
print('Overlay width: $overlayWidth');
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 بهبودهای آینده
|
||
|
||
### 1. Localization Integration
|
||
```dart
|
||
// اتصال به سیستم i18n Flutter
|
||
class LocalizationManager {
|
||
static void changeLocale(BuildContext context, String languageCode) {
|
||
// تغییر زبان کل اپ
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. Theme Integration
|
||
```dart
|
||
// تغییر زبان همراه با تغییر direction
|
||
void _changeLanguage(String code) {
|
||
final isRTL = ['ar', 'fa'].contains(code);
|
||
// اعمال تغییرات theme
|
||
}
|
||
```
|
||
|
||
### 3. Network Integration
|
||
```dart
|
||
// دریافت متنها از سرور
|
||
class LanguageService {
|
||
Future<Map<String, String>> getTranslations(String languageCode) {
|
||
// API call
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📞 پشتیبانی
|
||
|
||
برای مشکلات فنی یا پیشنهادات بهبود، با تیم توسعه تماس بگیرید.
|
||
|
||
**نسخه مستندات:** 1.0
|
||
**آخرین بروزرسانی:** 22 سپتامبر 2025
|
||
**نگارنده:** GitHub Copilot
|
||
|
||
---
|
||
|
||
*این مستندات برای توسعهدهندگان اپلیکیشن LBA تهیه شده است.* |